<?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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0+%D0%95%D0%BB%D0%B5%D0%BD%D0%B0</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0+%D0%95%D0%BB%D0%B5%D0%BD%D0%B0"/>
	<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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0"/>
	<updated>2026-10-22T16:01:21Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=20836</id>
		<title>Обсуждение участника:Почернина Елена</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=20836"/>
		<updated>2016-12-13T15:34:45Z</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;
* Исправьте сначала ошибки в формулах. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:36, 10 ноября 2016 (MSK)&lt;br /&gt;
** Можно уточнить, что именно неправильно, так как в основном формулы были взяты из литературы, описывающей данный алгоритм. Исправлена формула &amp;lt;math&amp;gt;\tau = {a_{jj} - a_{kk}}/{2a_{jk}}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\tau = {(a_{jj} - a_{kk})}/{2a_{jk}}&amp;lt;/math&amp;gt; в двух местах. --[[Участник: Почернина Елена|Почернина Елена]] 23:40, 13 ноября 2016 (MSK)&lt;br /&gt;
*** В принципе, нормально, глаз именно за эту зацепился. Есть ещё претензии к их стилю (дроби косой чертой - не очень хорошо), но по существу стало правильно. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 10:08, 16 ноября 2016 (MSK)&lt;br /&gt;
**** Хорошо. Стиль тоже исправила. --[[Участник: Почернина Елена|Почернина Елена]] 22:25, 18 ноября 2016 (MSK)&lt;br /&gt;
***** Осталось при совпадении двух диагональных элементов формулы выписать, знак можно интерпретировать по-разному. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 15:53, 5 декабря 2016 (MSK)&lt;br /&gt;
****** Добавили. --[[Участник: Почернина Елена|Почернина Елена]] 18:30, 13 декабря 2016 (MSK)&lt;br /&gt;
* По вращению уточню, что линейная там сложность - в последовательном варианте. В параллельном основная сложность там не вращение (которое O(1)), а предвычисление 3 элементов G^T G, Но их можно за логарифм вычислить (как скалярные произведения). Это надо бы указать в разделе по параллельной сложности. В остальном если и есть что-то - по большей части стиль, а не существо. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 10:14, 16 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующие части ===&lt;br /&gt;
* Не указан вклад каждого из авторов статьи. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* Графы на рис.1 и особенно 2 слишком мелкие. Не показана информационная структура вершин &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}, J, GR, JR&amp;lt;/math&amp;gt;. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
* Рисунок в разделе 2.4 не пронумерован. Единицы измерения не подписаны. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&lt;br /&gt;
* Непонятно, откуда делается вывод &amp;quot;При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает&amp;quot; - по рисунку это точно невозможно увидеть. На рисунке даже сложно понять, есть ли какое-то ускорение при увеличении числа процессоров и фиксированном размере матрицы. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какая версия MKL и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&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:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=20835</id>
		<title>Обсуждение участника:Почернина Елена</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=20835"/>
		<updated>2016-12-13T15:34:33Z</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;
* Исправьте сначала ошибки в формулах. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:36, 10 ноября 2016 (MSK)&lt;br /&gt;
** Можно уточнить, что именно неправильно, так как в основном формулы были взяты из литературы, описывающей данный алгоритм. Исправлена формула &amp;lt;math&amp;gt;\tau = {a_{jj} - a_{kk}}/{2a_{jk}}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\tau = {(a_{jj} - a_{kk})}/{2a_{jk}}&amp;lt;/math&amp;gt; в двух местах. --[[Участник: Почернина Елена|Почернина Елена]] 23:40, 13 ноября 2016 (MSK)&lt;br /&gt;
*** В принципе, нормально, глаз именно за эту зацепился. Есть ещё претензии к их стилю (дроби косой чертой - не очень хорошо), но по существу стало правильно. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 10:08, 16 ноября 2016 (MSK)&lt;br /&gt;
**** Хорошо. Стиль тоже исправила. --[[Участник: Почернина Елена|Почернина Елена]] 22:25, 18 ноября 2016 (MSK)&lt;br /&gt;
***** Осталось при совпадении двух диагональных элементов формулы выписать, знак можно интерпретировать по-разному. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 15:53, 5 декабря 2016 (MSK)&lt;br /&gt;
****** Добавили. [[Участник: Почернина Елена|Почернина Елена]] 18:30, 13 декабря 2016 (MSK)&lt;br /&gt;
* По вращению уточню, что линейная там сложность - в последовательном варианте. В параллельном основная сложность там не вращение (которое O(1)), а предвычисление 3 элементов G^T G, Но их можно за логарифм вычислить (как скалярные произведения). Это надо бы указать в разделе по параллельной сложности. В остальном если и есть что-то - по большей части стиль, а не существо. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 10:14, 16 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующие части ===&lt;br /&gt;
* Не указан вклад каждого из авторов статьи. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* Графы на рис.1 и особенно 2 слишком мелкие. Не показана информационная структура вершин &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}, J, GR, JR&amp;lt;/math&amp;gt;. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
* Рисунок в разделе 2.4 не пронумерован. Единицы измерения не подписаны. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&lt;br /&gt;
* Непонятно, откуда делается вывод &amp;quot;При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает&amp;quot; - по рисунку это точно невозможно увидеть. На рисунке даже сложно понять, есть ли какое-то ускорение при увеличении числа процессоров и фиксированном размере матрицы. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какая версия MKL и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=20834</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=20834"/>
		<updated>2016-12-13T15:33:31Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;(a_{jj} = a_{kk})&amp;lt;/math&amp;gt; считаем &amp;lt;math&amp;gt;\theta = \frac{\pi}{4}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
* минимальная эффективность реализации: 0.0095%&lt;br /&gt;
* максимальная эффективность реализации: 0.929%&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение производительности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
[[File:JacobiEfficiency.PNG|center|thumb|900px|Рисунок 8. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости реализации метода Якоби вычисления сингулярных чисел и векторов:&lt;br /&gt;
* По числу потоков: при увеличении числа потоков эффективность на рассмотренной области увеличивается при переходе от двух потоков к трем. Дальнейшее увеличение количества потоков приводит к снижению эффективности. &lt;br /&gt;
* По размеру задачи: наибольшая производительность достигается на матрицах размера 300x300 и 400x400. Дальнейшее увеличение размера матрицы не приводит к увеличению производительности. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=20363</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=20363"/>
		<updated>2016-12-08T13:03:34Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;(a_{jj} = a_{kk})&amp;lt;/math&amp;gt; считаем &amp;lt;math&amp;gt;\theta = \frac{\pi}{4}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
* минимальная эффективность реализации: 0.0095%&lt;br /&gt;
* максимальная эффективность реализации: 0.929%&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение производительности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
[[File:JacobiEfficiency.PNG|center|thumb|900px|Рисунок 8. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости реализации метода Якоби вычисления сингулярных чисел и векторов:&lt;br /&gt;
* По числу потоков: при увеличении числа потоков эффективность на рассмотренной области увеличивается при переходе от двух потоков к трем. Дальнейшее увеличение количества потоков приводит к снижению эффективности. &lt;br /&gt;
* По размеру задачи: наибольшая производительность достигается на матрицах размера 300x300 и 400x400. Дальнейшее увеличение размера матрицы не приводит к увеличению производительности. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=20362</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=20362"/>
		<updated>2016-12-08T13:02:58Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;(a_{jj} = a_{kk})&amp;lt;/math&amp;gt; считаем &amp;lt;math&amp;gt;\theta = \frac{\pi}{4}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
* минимальная эффективность реализации: 0.0095%&lt;br /&gt;
* максимальная эффективность реализации: 0.929%&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение производительности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
[[File:JacobiEfficiency.PNG|center|thumb|900px|Рисунок 8. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости реализации метода Якоби вычисления сингулярных чисел и векторов:&lt;br /&gt;
* По числу потоков: при увеличении числа потоков эффективность на рассмотренной области увеличивается при переходе от двух потоков к трем. Дальнейшее увеличение количества потоков приводит к снижению эффективности. &lt;br /&gt;
* По размеру задачи: наибольшая производительность достигается на матрицах размера 300x300 и 400x400. Дальнейшее увеличение размера матрицы не приводит к увеличению производительности. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18469</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18469"/>
		<updated>2016-11-19T12:28:33Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
* минимальная эффективность реализации: 0.0095%&lt;br /&gt;
* максимальная эффективность реализации: 0.929%&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение производительности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
[[File:JacobiEfficiency.PNG|center|thumb|900px|Рисунок 8. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости реализации метода Якоби вычисления сингулярных чисел и векторов:&lt;br /&gt;
* По числу потоков: при увеличении числа потоков эффективность на рассмотренной области увеличивается при переходе от двух потоков к трем. Дальнейшее увеличение количества потоков приводит к снижению эффективности. &lt;br /&gt;
* По размеру задачи: наибольшая производительность достигается на матрицах размера 300x300 и 400x400. Дальнейшее увеличение размера матрицы не приводит к увеличению производительности. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18468</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18468"/>
		<updated>2016-11-19T12:27:16Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
* минимальная эффективность реализации: 0.0095%&lt;br /&gt;
* максимальная эффективность реализации: 0.929%&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение производительности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
[[File:JacobiEfficiency.PNG|center|thumb|900px|Рисунок 8. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости реализации метода Якоби вычисления сингулярных чисел и векторов:&lt;br /&gt;
* По числу потоков: при увеличении числа потоков эффективность на рассмотренной области увеличивается при переходе от двух потоков к трем. Дальнейшее увеличение количества потоков приводит к снижению эффективности. &lt;br /&gt;
* По размеру задачи: наибольшая производительность достигается на матрицах размера 300x300 и 400x400. Дальнейшее увеличение размера матрицы не приводит к увеличению производительности. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18467</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18467"/>
		<updated>2016-11-19T12:25:53Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
* минимальная эффективность реализации: 0.0095%&lt;br /&gt;
* максимальная эффективность реализации: 0.929%&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение производительности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
[[File:JacobiEfficiency.PNG|center|thumb|900px|Рисунок 8. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости реализации метода Якоби вычисления сингулярных чисел и векторов:&lt;br /&gt;
* По числу потоков: при увеличении числа потоков эффективность на рассмотренной области увеличивается при переходе от двух потоков к трем. Дальнейшее увеличение количества потоков приводит к снижению эффективности. &lt;br /&gt;
* По размеру задачи: наибольшая производительность достигается на матрицах размера &amp;lt;math&amp;gt;300&amp;lt;/math&amp;gt;x&amp;lt;math&amp;gt;300&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;400&amp;lt;/math&amp;gt;x&amp;lt;math&amp;gt;400&amp;lt;/math&amp;gt;. Дальнейшее увеличение размера матрицы не приводит к увеличению производительности. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18466</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18466"/>
		<updated>2016-11-19T12:10: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение производительности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
[[File:JacobiEfficiency.PNG|center|thumb|900px|Рисунок 8. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
* минимальная эффективность реализации: 0.0095%&lt;br /&gt;
* максимальная эффективность реализации: 0.929%&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18465</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18465"/>
		<updated>2016-11-19T12:09:56Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение производительности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
[[File:JacobiEfficiency.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессов и размера матрицы]]&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
* минимальная эффективность реализации: 0.0095%&lt;br /&gt;
* максимальная эффективность реализации: 0.929%&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%A4%D0%B0%D0%B9%D0%BB:Averagetime.PNG&amp;diff=18464</id>
		<title>Файл:Averagetime.PNG</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Averagetime.PNG&amp;diff=18464"/>
		<updated>2016-11-19T12:08:15Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: Почернина Елена загрузил новую версию Файл:Averagetime.PNG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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%A4%D0%B0%D0%B9%D0%BB:JacobiPerformance.PNG&amp;diff=18463</id>
		<title>Файл:JacobiPerformance.PNG</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:JacobiPerformance.PNG&amp;diff=18463"/>
		<updated>2016-11-19T12:07:09Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: Почернина Елена загрузил новую версию Файл:JacobiPerformance.PNG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18460</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18460"/>
		<updated>2016-11-19T11:24:32Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Производительность]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18459</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18459"/>
		<updated>2016-11-19T11:20: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[File:JacobiPerformance.PNG|center|thumb|900px|Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Производительность]]&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%A4%D0%B0%D0%B9%D0%BB:JacobiPerformance.PNG&amp;diff=18458</id>
		<title>Файл:JacobiPerformance.PNG</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:JacobiPerformance.PNG&amp;diff=18458"/>
		<updated>2016-11-19T11:19:01Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18457</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18457"/>
		<updated>2016-11-19T11:05: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[File:Averagetime.PNG|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%A4%D0%B0%D0%B9%D0%BB:Averagetime.PNG&amp;diff=18456</id>
		<title>Файл:Averagetime.PNG</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Averagetime.PNG&amp;diff=18456"/>
		<updated>2016-11-19T11:03:17Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18445</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18445"/>
		<updated>2016-11-19T10:03: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18393</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18393"/>
		<updated>2016-11-18T21:17:50Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. &lt;br /&gt;
&lt;br /&gt;
Основную сложность в процедуре вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; представляет вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;, которое можно производить параллельно. Вычисление элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;  требует порядка &amp;lt;math&amp;gt;O(logN)&amp;lt;/math&amp;gt; операций. Вычисление элементов матриц &amp;lt;math&amp;gt;GR, JR&amp;lt;/math&amp;gt; в параллельной реализации требует &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[File: SQU3CTh5bI41.jpg|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18365</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18365"/>
		<updated>2016-11-18T21:00:53Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[File: SQU3CTh5bI41.jpg|center|thumb|900px|Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18351</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18351"/>
		<updated>2016-11-18T20:57:07Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
При запуске использовалась версия mkl 11.2.0. &lt;br /&gt;
&lt;br /&gt;
Компилятор icc запускался со следующими опциями: -DMKL_ILP64 -qopenmp -I${MKLROOT}/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_core.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm -ldl&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: SQU3CTh5bI41.jpg | Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=18268</id>
		<title>Обсуждение участника:Почернина Елена</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=18268"/>
		<updated>2016-11-18T19:26:19Z</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;
* Исправьте сначала ошибки в формулах. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:36, 10 ноября 2016 (MSK)&lt;br /&gt;
** Можно уточнить, что именно неправильно, так как в основном формулы были взяты из литературы, описывающей данный алгоритм. Исправлена формула &amp;lt;math&amp;gt;\tau = {a_{jj} - a_{kk}}/{2a_{jk}}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\tau = {(a_{jj} - a_{kk})}/{2a_{jk}}&amp;lt;/math&amp;gt; в двух местах. --[[Участник: Почернина Елена|Почернина Елена]] 23:40, 13 ноября 2016 (MSK)&lt;br /&gt;
*** В принципе, нормально, глаз именно за эту зацепился. Есть ещё претензии к их стилю (дроби косой чертой - не очень хорошо), но по существу стало правильно. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 10:08, 16 ноября 2016 (MSK)&lt;br /&gt;
**** Хорошо. Стиль тоже исправила. --[[Участник: Почернина Елена|Почернина Елена]] 22:25, 18 ноября 2016 (MSK)&lt;br /&gt;
* По вращению уточню, что линейная там сложность - в последовательном варианте. В параллельном основная сложность там не вращение (которое O(1)), а предвычисление 3 элементов G^T G, Но их можно за логарифм вычислить (как скалярные произведения). Это надо бы указать в разделе по параллельной сложности. В остальном если и есть что-то - по большей части стиль, а не существо. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 10:14, 16 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующие части ===&lt;br /&gt;
* Не указан вклад каждого из авторов статьи. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* Графы на рис.1 и особенно 2 слишком мелкие. Не показана информационная структура вершин &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}, J, GR, JR&amp;lt;/math&amp;gt;. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
* Рисунок в разделе 2.4 не пронумерован. Единицы измерения не подписаны. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&lt;br /&gt;
* Непонятно, откуда делается вывод &amp;quot;При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает&amp;quot; - по рисунку это точно невозможно увидеть. На рисунке даже сложно понять, есть ли какое-то ускорение при увеличении числа процессоров и фиксированном размере матрицы. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какая версия MKL и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&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:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=18267</id>
		<title>Обсуждение участника:Почернина Елена</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=18267"/>
		<updated>2016-11-18T19:25:53Z</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;
* Исправьте сначала ошибки в формулах. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:36, 10 ноября 2016 (MSK)&lt;br /&gt;
** Можно уточнить, что именно неправильно, так как в основном формулы были взяты из литературы, описывающей данный алгоритм. Исправлена формула &amp;lt;math&amp;gt;\tau = {a_{jj} - a_{kk}}/{2a_{jk}}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\tau = {(a_{jj} - a_{kk})}/{2a_{jk}}&amp;lt;/math&amp;gt; в двух местах. [[Участник: Почернина Елена|Почернина Елена]] 23:40, 13 ноября 2016 (MSK)&lt;br /&gt;
*** В принципе, нормально, глаз именно за эту зацепился. Есть ещё претензии к их стилю (дроби косой чертой - не очень хорошо), но по существу стало правильно. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 10:08, 16 ноября 2016 (MSK)&lt;br /&gt;
**** Хорошо. Стиль тоже исправила. [[Участник: Почернина Елена|Почернина Елена]] 22:25, 18 ноября 2016 (MSK)&lt;br /&gt;
* По вращению уточню, что линейная там сложность - в последовательном варианте. В параллельном основная сложность там не вращение (которое O(1)), а предвычисление 3 элементов G^T G, Но их можно за логарифм вычислить (как скалярные произведения). Это надо бы указать в разделе по параллельной сложности. В остальном если и есть что-то - по большей части стиль, а не существо. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 10:14, 16 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующие части ===&lt;br /&gt;
* Не указан вклад каждого из авторов статьи. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* Графы на рис.1 и особенно 2 слишком мелкие. Не показана информационная структура вершин &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}, J, GR, JR&amp;lt;/math&amp;gt;. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
* Рисунок в разделе 2.4 не пронумерован. Единицы измерения не подписаны. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&lt;br /&gt;
* Непонятно, откуда делается вывод &amp;quot;При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает&amp;quot; - по рисунку это точно невозможно увидеть. На рисунке даже сложно понять, есть ли какое-то ускорение при увеличении числа процессоров и фиксированном размере матрицы. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какая версия MKL и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:49, 16 ноября 2016 (MSK)&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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18263</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18263"/>
		<updated>2016-11-18T19:18:39Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: SQU3CTh5bI41.jpg | Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18262</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18262"/>
		<updated>2016-11-18T19:18: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{(|\tau| + \sqrt{1 + \tau^2})} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{|\tau| + \sqrt{1 + \tau^2}} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: SQU3CTh5bI41.jpg | Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18257</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18257"/>
		<updated>2016-11-18T19:10: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{(|\tau| + \sqrt{1 + \tau^2})} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{(|\tau| + \sqrt{1 + \tau^2})} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: SQU3CTh5bI41.jpg | Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18254</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18254"/>
		<updated>2016-11-18T19:10:10Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{a_{jj} - a_{kk}}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{(|\tau| + \sqrt{1 + \tau^2})} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{\sqrt{1 + t^2}} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{(a_{jj} - a_{kk})}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{(|\tau| + \sqrt{1 + \tau^2})} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{(\sqrt{1 + t^2})} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: SQU3CTh5bI41.jpg | Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18252</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18252"/>
		<updated>2016-11-18T19:08:53Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{(a_{jj} - a_{kk})}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{(|\tau| + \sqrt{1 + \tau^2})} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{(\sqrt{1 + t^2})} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{(a_{jj} - a_{kk})}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{(|\tau| + \sqrt{1 + \tau^2})} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{(\sqrt{1 + t^2})} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: SQU3CTh5bI41.jpg | Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18249</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=18249"/>
		<updated>2016-11-18T19:05: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= \frac{(a_{jj} - a_{kk})}{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= \frac{sign(\tau)}{(|\tau| + \sqrt{1 + \tau^2})} \\&lt;br /&gt;
         c &amp;amp;= \frac{1}{(\sqrt{1 + t^2})} \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: SQU3CTh5bI41.jpg | Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17439</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17439"/>
		<updated>2016-11-15T20:33:23Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: SQU3CTh5bI41.jpg | Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17434</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17434"/>
		<updated>2016-11-15T20:29:31Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: SQU3CTh5bI41.jpg | Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
Наилучшая производительность достигается при использовании двух потоков. При дальнейшем увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17411</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17411"/>
		<updated>2016-11-15T20:08:33Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Масштабируемость алгоритма и его реализации|2.4]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]])&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17339</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17339"/>
		<updated>2016-11-15T18:17:11Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]])&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод Якоби&#039;&#039;&#039; позволяет найти сингулярное разложение плотной матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:16] с шагом 1;&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
[[file: Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17326</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17326"/>
		<updated>2016-11-15T17:41:17Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]])&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод Якоби&#039;&#039;&#039; позволяет найти сингулярное разложение плотной матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1, 2, 4, 8, 16, 32, 64, 96, 128, 160, 192, 224, 256];&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: Рисунок 6. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
&lt;br /&gt;
[[file: Рисунок 7. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17325</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=17325"/>
		<updated>2016-11-15T17:39:18Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]])&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод Якоби&#039;&#039;&#039; позволяет найти сингулярное разложение плотной матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Проведём исследование масштабируемости параллельной реализации метода Якоби нахождения сингулярных чисел и векторов. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1, 2, 4, 8, 16, 32, 64, 96, 128, 160, 192, 224, 256];&lt;br /&gt;
*	размер матрицы [100 : 900] с шагом 100.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график среднего времени работы алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file: Рисунок 8. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение времени выполнения в зависимости от числа процессоров и размера матрицы]]&lt;br /&gt;
[[file: Рисунок 9. Параллельная реализация метода Якоби вычисления сингулярных чисел и векторов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска падает. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://software.intel.com/ru-ru/node/521152#248AD4D8-005A-4800-9A73-428952BC1E44 Исследованная параллельная реализация, реализованная в библиотеке Intel MKL]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=16751</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=16751"/>
		<updated>2016-11-13T20:46:47Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]])&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод Якоби&#039;&#039;&#039; позволяет найти сингулярное разложение плотной матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=16745</id>
		<title>Обсуждение участника:Почернина Елена</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=16745"/>
		<updated>2016-11-13T20:39:25Z</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;
* Исправьте сначала ошибки в формулах. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:36, 10 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
** Можно уточнить, что именно неправильно, так как в основном формулы были взяты из литературы, описывающей данный алгоритм. Исправлена формула &amp;lt;math&amp;gt;\tau = {a_{jj} - a_{kk}}/{2a_{jk}}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\tau = {(a_{jj} - a_{kk})}/{2a_{jk}}&amp;lt;/math&amp;gt; в двух местах. [[Участник: Почернина Елена|Почернина Елена]] 23:40, 13 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующие части ===&lt;br /&gt;
* Не указан вклад каждого из авторов статьи. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* Графы на рис.1 и особенно 2 слишком мелкие. Не показана информационная структура вершин &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}, J, GR, JR&amp;lt;/math&amp;gt;. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=16737</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=16737"/>
		<updated>2016-11-13T20:31:24Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]])&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод Якоби&#039;&#039;&#039; позволяет найти сингулярное разложение плотной матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=16736</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=16736"/>
		<updated>2016-11-13T20:28:23Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]])&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод Якоби&#039;&#039;&#039; позволяет найти сингулярное разложение плотной матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {(a_{jj} - a_{kk})}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=16574</id>
		<title>Обсуждение участника:Почернина Елена</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=16574"/>
		<updated>2016-11-12T18:21:31Z</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;
* Исправьте сначала ошибки в формулах. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:36, 10 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
** Можно уточнить, что именно неправильно, так как в основном формулы были взяты из литературы, описывающей данный алгоритм. [[Участник: Почернина Елена|Почернина Елена]] 21:20, 12 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующие части ===&lt;br /&gt;
* Не указан вклад каждого из авторов статьи. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* Графы на рис.1 и особенно 2 слишком мелкие. Не показана информационная структура вершин &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}, J, GR, JR&amp;lt;/math&amp;gt;. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&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:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=16573</id>
		<title>Обсуждение участника:Почернина Елена</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0&amp;diff=16573"/>
		<updated>2016-11-12T18:20:54Z</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;
* Исправьте сначала ошибки в формулах. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:36, 10 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
* Можно уточнить, что именно неправильно, так как в основном формулы были взяты из литературы, описывающей данный алгоритм. [[Участник: Почернина Елена|Почернина Елена]] 21:20, 12 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующие части ===&lt;br /&gt;
* Не указан вклад каждого из авторов статьи. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* Графы на рис.1 и особенно 2 слишком мелкие. Не показана информационная структура вершин &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}, J, GR, JR&amp;lt;/math&amp;gt;. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:30, 25 октября 2016 (MSK)&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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=14934</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=14934"/>
		<updated>2016-10-30T20:30:12Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]])&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод Якоби&#039;&#039;&#039; позволяет найти сингулярное разложение плотной матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:Akj.png|Рисунок 2. Граф вычисления значений элементов &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 3. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:Gij.png|Рисунок 4. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;GR&amp;lt;/math&amp;gt;&lt;br /&gt;
File:Jij.png|Рисунок 5. Граф вычисления значений элементов матрицы &amp;lt;math&amp;gt;JR&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=14231</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=14231"/>
		<updated>2016-10-27T14:43:32Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]], группа 601 (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Существующие реализации алгоритма|2.7]]), [[Участница:Светлана|Костюкова Светлана]], группа 601 (разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]])&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод Якоби&#039;&#039;&#039; позволяет найти сингулярное разложение плотной матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=1200px&amp;gt;&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 2. Граф одной итерации алгоритма с вычислением матрицы вращения &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9233</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9233"/>
		<updated>2016-10-15T11:17:37Z</updated>

		<summary type="html">&lt;p&gt;Почернина Елена: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]] (группа 601), [[Участница:Светлана|Костюкова Светлана]] (группа 601)&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 2. Граф одной итерации алгоритма с отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9222</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9222"/>
		<updated>2016-10-15T11:13:14Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]] (группа 601), [[Участница:Светлана|Костюкова Светлана]] (группа 601)&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 2. Граф одной итерации алгоритма с отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK, ScaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9220</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9220"/>
		<updated>2016-10-15T11:11:43Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]] (группа 601), [[Участница:Светлана|Костюкова Светлана]] (группа 601)&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из трех групп вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 2. Граф одной итерации алгоритма с отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;V. Strumpen, H. Hoffmann, A. Agarwal A Stream Algorithm for the SVD, pp. 6-7, 23-24, http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-641.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK,scaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9189</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9189"/>
		<updated>2016-10-15T11:01:40Z</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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]] (группа 601), [[Участница:Светлана|Костюкова Светлана]] (группа 601)&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 2. Граф одной итерации алгоритма с отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK,scaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library, https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9186</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=9186"/>
		<updated>2016-10-15T11:01: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]] (группа 601), [[Участница:Светлана|Костюкова Светлана]] (группа 601)&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
File:JacobiSVD2.png|Рисунок 2. Граф одной итерации алгоритма с отображением входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
В данном алгоритме существует возможность параллельного вычисления вращений Якоби&amp;lt;ref&amp;gt;Halil Snopce, Ilir Spahiu Parallel Computation of the SVD, pp. 458-460, http://www.wseas.us/e-library/conferences/2011/Paris/ECC/ECC-73.pdf&amp;lt;/ref&amp;gt;. Максимальное количество вращений в данном методе равно &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В параллельной реализации, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - четное, можно выполнить &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; вращений параллельно, если &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - нечетное, то &amp;lt;math&amp;gt;\frac{n-1}{2}&amp;lt;/math&amp;gt; вращений. Также следует учесть, что сложность самой процедуры вращения &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039; равна &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;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;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK,scaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library,https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=8959</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=8959"/>
		<updated>2016-10-15T10:10: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]] (группа 601), [[Участница:Светлана|Костюкова Светлана]] (группа 601)&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: плотная матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK,scaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library,https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=8890</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%9F%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B0_%D0%95%D0%BB%D0%B5%D0%BD%D0%B0/%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%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2&amp;diff=8890"/>
		<updated>2016-10-15T09: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;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;2n^2 + n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Авторы статьи: [[Участник:Почернина Елена|Почернина Елена]] (группа 601), [[Участница:Светлана|Костюкова Светлана]] (группа 601)&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;G&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Такое разложение можно записать в виде &amp;lt;math&amp;gt;G = U\Sigma V^*&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; - унитарные (&#039;&#039;в вещественном случае - ортогональные&#039;&#039;) матрицы размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;×&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; с вещественными положительными числами на главной диагонали. Диагональные элементы матрицы &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; называются сингулярными числами матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, а столбцы матриц &amp;lt;math&amp;gt;U,V&amp;lt;/math&amp;gt; - левыми и правыми сингулярными векторами.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Неявный&#039;&#039;&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt; метод Якоби математически эквивалентен применению метода Якоби вычисления собственных значений к матрице &amp;lt;math&amp;gt;A = G^TG&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это значит, что на каждом шаге вычисляется вращение Якоби &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;, с помощью которого матрица &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; неявно пересчитывется в &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;; вращение выбрано так, чтобы пара внедиагональных элементов из &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; обратилась в нули в матрице &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt;. При этом ни &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, ни &amp;lt;math&amp;gt;J^TG^TGJ&amp;lt;/math&amp;gt; не вычисляются в явном виде; вместо них вычисляется матрица &amp;lt;math&amp;gt;GJ&amp;lt;/math&amp;gt;. Поэтому алгоритм называется &#039;&#039;методом односторонних вращений&#039;&#039;.&lt;br /&gt;
  &lt;br /&gt;
Метод Якоби для вычисления сингулярных чисел и векторов является самым медленным из имеющихся алгоритмов поиска сингулярных чисел и векторов, но тем не менее, интерес к нему сохраняется. Для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; он способен вычислять сингулярные числа и векторы намного точнее, чем другие методы. В частности, метод Якоби вычисляет сингулярные числа матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; с высокой точностью, если G может быть представлена в виде &amp;lt;math&amp;gt;G = DX&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; – диагональная матрица, а &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; – хорошо обусловлена. В этом случае заданная матрица обрабатывается без предварительного приведения к двухдиагональному виду, в то время как другие алгоритмы включают в себя приведение матрицы к двухдиагональной форме, из-за чего и теряют все верные разряды во всех сингулярных числах, кроме старшего.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt; - сингулярные числа, &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - матрица левых сингулярных векторов, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - матрица правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
Основной алгоритм заключается в следующем&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-264)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Для всех элементов матрицы &amp;lt;math&amp;gt;A^{(i)} = (G^TG)^{(i)}&amp;lt;/math&amp;gt;, находящихся вне главной диагонали &amp;lt;math&amp;gt;(a_{12}, a_{13},\dots, a_{1n}, a_{23}, a_{24},\dots, a_{2n},\dots, a_{n-1n})&amp;lt;/math&amp;gt; проверяем условие &amp;lt;math&amp;gt;|A_{jk}|&amp;lt;\varepsilon&amp;lt;/math&amp;gt;:&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| \le \varepsilon&amp;lt;/math&amp;gt;, то переходим к следующему элементу,&lt;br /&gt;
Если &amp;lt;math&amp;gt;|A_{jk}^{(i)}| &amp;gt; \varepsilon&amp;lt;/math&amp;gt;, то нужно выполнить вращение в плоскости &amp;lt;math&amp;gt;(jk)&amp;lt;/math&amp;gt;, после чего перейти к следующей итерации алгоритма.&lt;br /&gt;
Если на очередной итерации не было совершено ни одного вращения, значит матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; стала достаточна близка к диагональной, и можно перейти к вычислению искомых значений: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U = [u_1,\dots,u_n]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Одностороннее вращение в плоскости &amp;lt;math&amp;gt;(jk)&amp;lt;/math&amp;gt; осуществляет процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;math&amp;gt;R(j,k,\theta)&amp;lt;/math&amp;gt; - матрица вращений Якоби. Матрица вращений выбирается так, чтобы обнулить пару внедиагональных элементов&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 244-245)&amp;lt;/ref&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;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  &amp;amp;     &amp;amp;      &amp;amp;       &amp;amp; j &amp;amp;         &amp;amp; k &amp;amp;         &amp;amp;    &amp;amp;   \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&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) = &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;
&lt;br /&gt;
Для завершения описания алгоритма, нужно указать критерий останова, то есть объяснить смысл условия &#039;&#039;&amp;quot;если &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; не слишком мал&amp;quot;&#039;&#039;. Подходящим критерием останова является условие&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
|a_{jk}| \ge \varepsilon\sqrt{a_{jj}a_{kk}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро составляют множественные вычисления элементов матрицы &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;, а также вычисление промежуточной матрицы &amp;lt;math&amp;gt;GR(j, k, \theta)&amp;lt;/math&amp;gt; путем умножения исходной матрицы на матрицу вращения Якоби в процессе выполнения процедуры &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
После приведения матрицы &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; к виду, достаточно близкому к диагональному, вычисляются сингулярные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sigma_i = ||G(:,i)||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица левых сингулярных векторов  &amp;lt;math&amp;gt;U = [u_1,..., u_n]&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;u_i = G(:,i)/\sigma_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И (если требуется) матрица правых сингулярных векторов &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; путем накопления произведения вращений Якоби:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
V = J,&lt;br /&gt;
J = JR(j, k, \theta)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную часть метода составляет процедура односторонних вращений матрицы (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;). Рассмотрим подробнее структуру этой процедуры.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;a_{jk}, a_{jj}, a_{kk} (a_{ij} = (G^TG)_{ij})&amp;lt;/math&amp;gt;. В связи с тем, что нет необходимости каждый раз вычислять произведение &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt;, для вычисления каждого элемента требуется &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;\tau, c, s, t&amp;lt;/math&amp;gt; не представляют значительной вычислительной сложности.&lt;br /&gt;
&lt;br /&gt;
- Одностороннее вращение матрицы (умножение входной матрицы на матрицу вращения) требует порядка &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций. &lt;br /&gt;
&lt;br /&gt;
В итоге, процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039; требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма односторонних вращений необходимо вычислить искомые матрицы &amp;lt;math&amp;gt;S, U, V&amp;lt;/math&amp;gt; (матрица сингулярных чисел и матрицы левых и правых векторов).&lt;br /&gt;
&lt;br /&gt;
- Вычисление сингулярных чисел &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
- Вычисление &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Аналогично для матрицы &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Метод можно описать следующим образом&amp;lt;ref&amp;gt;Дж. Деммель «Вычислительная линейная алгебра» (стр. 261-263)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 repeat&lt;br /&gt;
     for &amp;lt;math&amp;gt;j=1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
         for &amp;lt;math&amp;gt;k=j+1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
             обратиться к процедуре &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
         end for&lt;br /&gt;
     end for&lt;br /&gt;
 пока &amp;lt;math&amp;gt;G^TG&amp;lt;/math&amp;gt; не станет достаточно близка к диагональной матрице&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;\sigma_{i} = ||G(:,i)||_2 &amp;lt;/math&amp;gt; (норма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го столбца в &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;)&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;U = [u_{1},\dots, u_{n}]&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i} = G(:,i)/\sigma_{i}&amp;lt;/math&amp;gt;&lt;br /&gt;
 Положить &amp;lt;math&amp;gt;V = J&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; - накопленное произведение вращений Якоби.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби для нахождения сингулярных чисел и векторов матрицы &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; также использует метод односторонних вращений (процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&#039;&#039;&#039;&#039;&#039;). Алгоритм выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 proc &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     вычислить &amp;lt;math&amp;gt;a_{jj} = (G^TG)_{jj}, a_{jk} = (G^TG)_{jk}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk} = (G^TG)_{kk}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;|a_{jk}|&amp;lt;/math&amp;gt; не слишком мал&lt;br /&gt;
         &amp;lt;math&amp;gt;&lt;br /&gt;
         \begin{align}&lt;br /&gt;
         \tau &amp;amp;= {a_{jj} - a_{kk}}/{2a_{jk}} \\&lt;br /&gt;
         t &amp;amp;= {sign(\tau)}/(|\tau| + \sqrt{1 + \tau^2}) \\&lt;br /&gt;
         c &amp;amp;= 1/(\sqrt{1 + t^2}) \\&lt;br /&gt;
         s &amp;amp;= ct \\&lt;br /&gt;
         G &amp;amp;= GR(j,k,\theta) \  \dots c=cos\theta, s=sin\theta \end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
         if нужны правые сингулярные векторы &lt;br /&gt;
             &amp;lt;math&amp;gt;J = JR(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
         end if&lt;br /&gt;
     end if&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для вычисления сингулярных чисел и векторов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; в последовательном варианте на каждой итерации алгоритма вызывается процедура &#039;&#039;&#039;&#039;&#039;One-Sided-Jacobi-Rotation&amp;lt;math&amp;gt;(G,j,k)&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;, сложность которой равна &amp;lt;math&amp;gt;O(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;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
&lt;br /&gt;
Таким образом, метод Якоби вычисления сингулярных чисел и векторов при классификации по последовательной сложности относится к алгоритмам с &#039;&#039;кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция - вычисление &amp;lt;math&amp;gt;a_{jj}, a_{jk}, a_{kk}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;j+1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин соответствует вычислению значений &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; для матрицы вращения&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин соответствует вычислению произведений матриц &amp;lt;math&amp;gt;GR(k,j, \theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JR(k,j, \theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width:{{#expr: 3 * (400 + 35) + 4 * (3 - 1) + 8}}px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gallery widths=400px heights=400px&amp;gt;&lt;br /&gt;
File:JacobiSVG.png|Рисунок 1. Граф одной итерации алгоритма без отображения входных и выходных данных.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Таким образом, при классификации по высоте ЯПФ метод Якоби относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, а при классификации по ширине ЯПФ — к алгоритмам со сложностью &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: плотная матрица &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;g_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A= G^TG&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;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;\Sigma = diag(\sigma_{i})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\sigma_{i}&amp;lt;/math&amp;gt;  - сингулярные числа, матрица &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; левых сингулярных векторов и матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; правых сингулярных векторов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^2 + n&amp;lt;/math&amp;gt; (так как матрица сингулярных чисел &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; - диагональная, то достаточно хранить вектор сингулярных чисел (элементы &amp;lt;math&amp;gt;\sigma_i&amp;lt;/math&amp;gt;), а также две матрицы &amp;lt;math&amp;gt;U, V&amp;lt;/math&amp;gt; левых и правых сингулярных векторов).&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Метод Якоби является самым медленным из имеющихся алгоритмов вычисления сингулярных чисел и сингулярных векторов матрицы. Тем не менее, для некоторых некоторых типов матриц &amp;lt;math&amp;gt;G&amp;lt;/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;
Данный раздел будет дополнен позже в связи с продлением срока сдачи (до 15 ноября).&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Несмотря на то, что метод Якоби является самым медленным из методов вычисления сингулярных чисел и векторов матрицы, он реализован в некоторых пакетах, например, LAPACK,scaLAPACK, Intel MKL&amp;lt;ref&amp;gt;Intel® Math Kernel Library,https://software.intel.com/ru-ru/node/521153#CAF8CA08-1C69-48F8-B0C3-B2B27AFA92FA&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Почернина Елена</name></author>
	</entry>
</feed>