<?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=Nikita</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=Nikita"/>
	<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/Nikita"/>
	<updated>2026-10-22T23:25:20Z</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:Nikita&amp;diff=21080</id>
		<title>Обсуждение участника:Nikita</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Nikita&amp;diff=21080"/>
		<updated>2016-12-16T21:36:39Z</updated>

		<summary type="html">&lt;p&gt;Nikita: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению:&lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.7 что обозначают серые вершины на графе?&lt;br /&gt;
&lt;br /&gt;
2. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;br /&gt;
&lt;br /&gt;
3. Ссылки на литературу внутри текста статьи не нашел.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап проверки:&#039;&#039;&#039;&lt;br /&gt;
Добавляйте сюда ответы на вопросы и ход исправлений. &lt;br /&gt;
Возможно появление дополнительных замечаний.&lt;br /&gt;
&lt;br /&gt;
1. Думаю, описание метода Пейли разумнее переместить в раздел &amp;quot;Математическое описание&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. В математическом описании желательно хотя бы минимально кратко обосновать корректность (что достаточно проверить (p-1)/2 квадратов, и что матрица будет состоять только из элементов +1 и -1). &lt;br /&gt;
&lt;br /&gt;
3. Исправить код. Есть как опечатки, так и ошибки. Вообще говоря, для любой похожей математической задачи необходимо писать тесты. Здесь он очевиден - проверить получившуюся матрицу по определению. В Algowiki тест вставлять не нужно, приведите его здесь.&lt;br /&gt;
&lt;br /&gt;
4. Информационный граф неправилен. У вас, скорее, отражена макроструктура. Алгоритм довольно прост, поэтому необходимо построить граф по всем правилам, где выход операции переходит строго на вход следующей операции. Разумно будет взять конкретный пример n=4. Лучше построить граф, как с данными, так и без них. Представленный граф тоже можно будет оставить для наглядности. Его основная проблема в том, что не видно, как функция построения итоговой матрицы обращается к элементам residual, что может быть важным для каких-либо архитектур.&lt;br /&gt;
&lt;br /&gt;
5. (22.11) с учетом ошибки и в параллельном коде, эксперимент в пункте 2.4. нужно провести заново.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исправления по второму этапу:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
На данный момент были исправлены все замечания. Скажите, пожалуйста, будут ли применяться штрафы в период правки замечаний?&lt;br /&gt;
&#039;&#039;Ответ:&#039;&#039; нет, если, как в вашем случае, происходит просто исправление, штрафов не будет. Но лучше всё же не тянуть, т.к. могут возникнуть новые комментарии.&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=21079</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=21079"/>
		<updated>2016-12-16T21:36:07Z</updated>

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

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

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

		<summary type="html">&lt;p&gt;Nikita: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению:&lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.7 что обозначают серые вершины на графе?&lt;br /&gt;
&lt;br /&gt;
2. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;br /&gt;
&lt;br /&gt;
3. Ссылки на литературу внутри текста статьи не нашел.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап проверки:&#039;&#039;&#039;&lt;br /&gt;
Добавляйте сюда ответы на вопросы и ход исправлений. &lt;br /&gt;
Возможно появление дополнительных замечаний.&lt;br /&gt;
&lt;br /&gt;
1. Думаю, описание метода Пейли разумнее переместить в раздел &amp;quot;Математическое описание&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. В математическом описании желательно хотя бы минимально кратко обосновать корректность (что достаточно проверить (p-1)/2 квадратов, и что матрица будет состоять только из элементов +1 и -1). &lt;br /&gt;
&lt;br /&gt;
3. Исправить код. Есть как опечатки, так и ошибки. Вообще говоря, для любой похожей математической задачи необходимо писать тесты. Здесь он очевиден - проверить получившуюся матрицу по определению. В Algowiki тест вставлять не нужно, приведите его здесь.&lt;br /&gt;
&lt;br /&gt;
4. Информационный граф неправилен. У вас, скорее, отражена макроструктура. Алгоритм довольно прост, поэтому необходимо построить граф по всем правилам, где выход операции переходит строго на вход следующей операции. Разумно будет взять конкретный пример n=4. Лучше построить граф, как с данными, так и без них. Представленный граф тоже можно будет оставить для наглядности. Его основная проблема в том, что не видно, как функция построения итоговой матрицы обращается к элементам residual, что может быть важным для каких-либо архитектур.&lt;br /&gt;
&lt;br /&gt;
5. (22.11) с учетом ошибки и в параллельном коде, эксперимент в пункте 2.4. нужно провести заново.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исправления по второму этапу:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
На данный момент были исправлены все замечания, кроме пункта 4. Скажите, пожалуйста, будут ли применяться штрафы в период правки замечаний?&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=19064</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=19064"/>
		<updated>2016-11-23T22:40:36Z</updated>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		<summary type="html">&lt;p&gt;Nikita: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Информационный граф алгоритма можно представить в виде четырёх последовательных блоков. Первый блок содержит &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания. А каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; порядок матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов является квадратичным. &lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма является постоянной (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Воеводин В.В., Воеводин Вл. В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002.&lt;br /&gt;
&lt;br /&gt;
[2] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11776</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11776"/>
		<updated>2016-10-15T20:24:16Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Информационный граф */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Информационный граф алгоритма можно представить в виде четырёх последовательных блоков. Первый блок содержит &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания. А каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; порядок матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов является квадратичным. &lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма является постоянной (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Воеводин В.В., Воеводин Вл. В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002.&lt;br /&gt;
&lt;br /&gt;
[2] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Lineprinter&amp;diff=11609</id>
		<title>Обсуждение участника:Lineprinter</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Lineprinter&amp;diff=11609"/>
		<updated>2016-10-15T20:01:31Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Перенос */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Перенос ==&lt;br /&gt;
Статья: [[Кластеризация сетями Кохонена]]&lt;br /&gt;
Выполняют: [[Участник:Kravtsovkirill| Кравцов Кирилл]] и [[Участник:Emaksimov| Максимов Егор]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нахождение собственных чисел квадратной матрицы методом QR разложения (2)]]&lt;br /&gt;
Выполняют: Баев Олег и Шевелев Александр&lt;br /&gt;
&lt;br /&gt;
Статья: [[Стабилизированный метод биспоряженных градиентов (BiCGSTAB)]]&lt;br /&gt;
Выполняют: Гаврилов Алексей и Новиков Александр&lt;br /&gt;
&lt;br /&gt;
Статья: [[Участники: Бобошко А., Юмакаева А./Решение начальной задачи Коши для системы ОДУ методом Рунге-Кутта 4-го порядка]];&lt;br /&gt;
Выполняют: Бобошко Алексей и Юмакаева Алина&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на сетях Кохоннена]];&lt;br /&gt;
Выполняют:  Логвиненко Александра и Адиев Тохтар&lt;br /&gt;
&lt;br /&gt;
Статья: [[Ортогонализация Грама-Шмидта]];&lt;br /&gt;
Выполняют: [[Участник:KibAndrey| Кибанов Андрей]] и Аджиева Татьяна&lt;br /&gt;
&lt;br /&gt;
Статья: [[Самоорганизующиеся карты Кохонена]];&lt;br /&gt;
Выполняет: [[Участник:Anton goy| Гой Антон]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[ЕМ-алгоритм_(Тематическое_моделирование)]];&lt;br /&gt;
Выполняют: Мурат Апишев и Андрей Заночкин&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_Ланцоша_с_полной_переортогонализацией]];&lt;br /&gt;
Выполняет:[[Участник:Sfedotov| Федотов С.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_k-средних]]&lt;br /&gt;
Выполняют: [[Участник:Error2407|Богомазов Евгений]], [[Участник:Илья_Егоров|Егоров Илья]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм k-means]]&lt;br /&gt;
Выполняют: [[Участник:Бротиковская Данута|Данута Бротиковская]] и [[Участник:DennZo1993|Денис Зобнин]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Partitioning Around Medoids (Алгоритм)]]&lt;br /&gt;
Выполняют: [[Участник:Denemmy| Галеев Данил]] и [[Участник:Ivan.Z| Запутляев Иван]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нечеткий_алгоритм_С_средних]]&lt;br /&gt;
Выполняют: [[Участник:Demon smd|Д.А.Гуськов]], [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Решение_задачи_Коши_для_системы_ОДУ_методом_Рунге-Кутты_4_порядка]];&lt;br /&gt;
Выполняют: [[Участник:Алимов_Дамир_Алиевич|Алимов Дамир]] и [[Участник:Anlesnichiy|Антон Лесничий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Строгий_алгоритм_С_средних_(Hard_C-Means,_HCM)]];&lt;br /&gt;
Выполняют: [[Участник:Светлана_Лукьяненко|Лукьяненко Светлана]] и [[Участник:Юрий_Комаров|Комаров Юрий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на минимальном остовном дереве]];&lt;br /&gt;
Выполняет: [[Участник:Astandrik | Стандрик Антон Сергеевич]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Умножение разреженной матрицы на вектор]];&lt;br /&gt;
Выполняет: [[Участник:Lexaloris | Новоселов Алексей]], Выполняет: [[Участник:kochet|П.А. Кочетков]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нахождение_собственных_чисел_квадратной_матрицы_методом_QR_разложения_(3)|Нахождение собственных чисел квадратной матрицы методом QR разложения (3)]];&lt;br /&gt;
Выполняют: [[Участник:Смирнова_Александра|Смирнова А.С.]], [[Участник:Александра_Киямова|Киямова А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Якоби_вычисления_сингулярных_чисел_и_векторов]];&lt;br /&gt;
Выполняют: [[Участница:Почернина_Елена| Почернина Елена]] и [[Участница:Светлана|Костюкова Светлана]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Ньютона_для_решения_систем_нелинейных_уравнений(2)]];&lt;br /&gt;
Выполняют: [[Участник:Oleggium|Гирняк О.Р.]], [[Участник:Dimx19|Васильков Д.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_кластеризации_с_использованием_представлений]];&lt;br /&gt;
Выполняют: [[Участник:Cookie|Шатков С.А.]], [[Участница:JuliaA|Антохина Ю.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_преобразование_Фурье_(FFT)|Быстрое преобразование Фурье (FFT)]];&lt;br /&gt;
Выполняют: [[Участник:Victoria_Stepanischeva|Степанищева Виктория]] и [[Участник:Igor_Munkin|Мунькин Игорь]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_дискретное_преобразование_Фурье|Быстрое_дискретное_преобразование_Фурье]];&lt;br /&gt;
Выполняют: [[Участник:ivanov.kir.m | К.М.Иванов]], [[Участник:Pumpkin | А.C.Сапин]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k_средних]]&lt;br /&gt;
Выполняют: [[Участник:Parkhomenko|Пархоменко Павел]], [[Участник:ivan.mashonskiy|Машонский Иван]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[EM-алгоритм_кластеризации]]&lt;br /&gt;
Выполняет: [[Участник:Noite|Зинченко Дмитрий]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k_means]]&lt;br /&gt;
Выполняют: [[Участник:IanaV| Валуйская Яна]], [[Участник:GlotovES| Глотов Евгений]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод Якоби вычисления собственных значений симметричной матрицы ЗП |Метод Якоби вычисления собственных значений симметричной матрицы ЗП]];&lt;br /&gt;
Выполняют: [[Участник:Зиновьев Владимир|Зиновьев В.С.]], [[Участник:Пронин Андрей|Пронин А.М.]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_кластеризации,_основанный_на_минимальном_покрывающем_дереве]]&lt;br /&gt;
Выполняет: [[Участник:Kanast74|Дмитриева Анастасия]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Нахождение_собственных_чисел_квадратной_матрицы_методом_QR_разложения_(4)]]&lt;br /&gt;
Выполняют: [[Участник:F-morozov|Морозов Ф. В.]], [[Участник:Nataliya|Пащенко Н. Ф.]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Хранение_ненулевых_элементов_разреженных_матриц._Умножение_разреженной_матрицы_на_вектор]];&lt;br /&gt;
Выполняют: [[Участник:Trrufina|Третьякова Р.М.]] и [[Участник:Екатерина_Буторина|Буторина Е.В.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_кластеризации_с_использованием_представлений2]];&lt;br /&gt;
Выполняет: [[Участник:Лукьянова Анна|Лукьянова А.Я.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод Якоби вычисления собственных значений симметричной матрицы]];&lt;br /&gt;
Выполняют: [[Участник: Galkina|Галкина А.С.]], [[Участник: Игорь|Плахов И.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод рекурсивной координатной бисекции]];&lt;br /&gt;
Выполняют: [[Участник: Obirvalger|Гордеев Михаил]], [[Участник: KolmakovEA|Колмаков Евгений]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Итерационный метод решения системы линейных алгебраических уравнений GMRES (обобщенный метод минимальных невязок)]];&lt;br /&gt;
Выполняют: [[Участник: Эльвира Ахиярова|Ахиярова Эльвира]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Хранение ненулевых элементов разреженной матрицы. Умножение разреженной матрицы на вектор]];&lt;br /&gt;
Выполняют: [[Участник: Janyell|Сычева Евгения]], [[Участник: Ahahalin|Хахалин Анатолий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Построение матрицы Адамара произвольного размера]];&lt;br /&gt;
Выполняют: [[Участник: Бугаков Юрий|Бугаков Юрий]], Кужамалиев Ернур&lt;br /&gt;
&lt;br /&gt;
Статья: [[Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)]]&lt;br /&gt;
Выполняют: [[Участница:Sannikovats| Санникова Татьяна Сергеевна]], [[Участник:Plukshin| Лукшин Петр Андреевич]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на построении каркаса]];&lt;br /&gt;
Выполняют: [[Участник:SenderovichNikita| Сендерович Никита]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на максимизации ожидания]];&lt;br /&gt;
Выполняют: Готман Мария, Лукашкина Юлия&lt;br /&gt;
&lt;br /&gt;
Статья: [[Partitioning_Around_Medoids_(PAM)]]&lt;br /&gt;
Выполняют: [[Участник:Avasilenko|А.Э.Василенко]], [[Участник:Anastasia|А.В.Тузикова]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нечеткий алгоритм С-средних (Fuzzy C-means)]]&lt;br /&gt;
Выполняют: [[Участник:Nikmedoed|Н.А. Муромцев]], [[Участник:illusive_mike|М.С. Дворецкий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нечеткий алгоритм C средних]]&lt;br /&gt;
Выполняют: [[Участник:Gkhazeeva|Гелана Хазеева]], [[Участник:Yushin|Павел Юшин]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Плотностный алгоритм кластеризации DBSCAN]]&lt;br /&gt;
Выполняют: [[Участник:Elena777mc|Малахова Е.С.]], [[Участник:Жаннат_Сагиолданова|Сагиолданова Ж.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Кластеризация Partitioning Around Medoids (PAM)]]&lt;br /&gt;
Выполняют:[[ Участник:Тодуа Антон| Тодуа Антон]], [[Участник:Гусева Юлия| Гусева Юлия]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Участник:Бугаков Юрий (613 группа), Кужамалиев Ернур (601 группа)/Построение матрицы Адамара произвольной размерности]]&lt;br /&gt;
Выполняют:[[ Участник:Бугаков Юрий| Бугаков Юрий]], [[Участник:Кужамалиев Ернур| Кужамалиев Ернур]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Участник:Nikita/Построение_матрицы_Адамара|Построение матрицы Адамара]]&lt;br /&gt;
Выполняют: [[Участник:Nikita|Иванов Никита]], [[Участник:Tsyganov Nikita|Цыганов Никита]]&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11573</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11573"/>
		<updated>2016-10-15T19:53:28Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Литература */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Информационный граф алгоритма можно представить в виде четырёх последовательных блоков. Первый блок содержит &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания. А каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; порядок матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов является квадратичным. &lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма является постоянной (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Воеводин В.В., Воеводин Вл. В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002.&lt;br /&gt;
&lt;br /&gt;
[2] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita&amp;diff=11411</id>
		<title>Участник:Nikita</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita&amp;diff=11411"/>
		<updated>2016-10-15T19:25:58Z</updated>

		<summary type="html">&lt;p&gt;Nikita: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Иванов Никита Валерьевич, группа 611&lt;br /&gt;
&lt;br /&gt;
МГУ им. М.В.Ломоносова, факультет ВМК, кафедра Исследования Операций.&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11363</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11363"/>
		<updated>2016-10-15T19:19:06Z</updated>

		<summary type="html">&lt;p&gt;Nikita: &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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Информационный граф алгоритма можно представить в виде четырёх последовательных блоков. Первый блок содержит &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания. А каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; порядок матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов является квадратичным. &lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма является постоянной (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11323</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11323"/>
		<updated>2016-10-15T19:12:53Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Свойства алгоритма */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Информационный граф алгоритма можно представить в виде четырёх последовательных блоков. Первый блок содержит &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания. А каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; порядок матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов является квадратичным. &lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма является постоянной (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11285</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=11285"/>
		<updated>2016-10-15T19:07:13Z</updated>

		<summary type="html">&lt;p&gt;Nikita: &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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Информационный граф алгоритма можно представить в виде четырёх последовательных блоков. Первый блок содержит &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания. А каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; порядок матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita&amp;diff=11205</id>
		<title>Участник:Nikita</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita&amp;diff=11205"/>
		<updated>2016-10-15T18:53:15Z</updated>

		<summary type="html">&lt;p&gt;Nikita: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Иванов Никита, студент 611 группы&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=10965</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=10965"/>
		<updated>2016-10-15T17:55:18Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Информационный граф */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c++&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Информационный граф алгоритма можно представить в виде четырёх последовательных блоков. Первый блок содержит &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания. А каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#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;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=10078</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=10078"/>
		<updated>2016-10-15T14:57:15Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Входные и выходные данные алгоритма */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c++&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+2n-2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; порядок матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=9066</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=9066"/>
		<updated>2016-10-15T10:36:20Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Существующие реализации алгоритма */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c++&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+2n-2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=8999</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=8999"/>
		<updated>2016-10-15T10:20:41Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Литература */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c++&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+2n-2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из чего следует, что алгоритм имеет квадратичную последовательную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7616</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7616"/>
		<updated>2016-10-14T14:53:39Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Литература */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Известно большое число методов построения, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c++&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] http://info.sernam.ru/book_tcod.php?id=16&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7606</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7606"/>
		<updated>2016-10-14T14:37:18Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Литература */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Известно большое число методов построения, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7601</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7601"/>
		<updated>2016-10-14T14:26:56Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Метод Пейли */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Известно большое число методов построения, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7600</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7600"/>
		<updated>2016-10-14T14:25:57Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Метод Пейли */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Известно большое число методов построения, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7584</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7584"/>
		<updated>2016-10-14T14:12:58Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Общее описание алгоритма */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Известно большое число методов построения, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij}))&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из математического описания, алгоритм основан на простейших операциях с числами, поэтому макроструктура алгоритма полностью соответствует его математическому описанию.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7471</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7471"/>
		<updated>2016-10-14T12:59:46Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Общее описание алгоритма */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Для матриц Адамара справедлива следующая &#039;&#039;&#039;гипотеза&#039;&#039;&#039;: если существует матрица Адамара порядка n, то n равно 1 или 2 или делится на 4, однако до сих пор не была доказана.&lt;br /&gt;
&lt;br /&gt;
Примеры матриц (1,2,4,8)&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Известно большое число методов построения, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
Сначала мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_ij)&amp;lt;/math&amp;gt;. Она представляет собой (pxp)-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_ij=X(j-i)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля, вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;r_i=r_{i-p}&amp;lt;/math&amp;gt;), которые, в свою очередь, определяются следующим образом:&lt;br /&gt;
** &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
** &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. Элементы находятся следующим образом:&lt;br /&gt;
** &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
# Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;;&lt;br /&gt;
# Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания вида &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7410</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7410"/>
		<updated>2016-10-14T12:12:16Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Общее описание алгоритма */&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^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
&lt;br /&gt;
Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной.&lt;br /&gt;
&lt;br /&gt;
Для матриц Адамара справедливо следующее утверждение: если существует матрица Адамара порядка n, то n равно 1 или 2 или делится на 4.&lt;br /&gt;
&lt;br /&gt;
Примеры матриц (1,2,4,8)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные - это порядок генерируемой матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, удовлетворяющее следующим свойствам: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идет от нуля, первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов образуются следующим образом:&lt;br /&gt;
** ыфвыв &lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7207</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7207"/>
		<updated>2016-10-14T09:25:35Z</updated>

		<summary type="html">&lt;p&gt;Nikita: &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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7205</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7205"/>
		<updated>2016-10-14T09:25:23Z</updated>

		<summary type="html">&lt;p&gt;Nikita: &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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7201</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7201"/>
		<updated>2016-10-14T09:23:49Z</updated>

		<summary type="html">&lt;p&gt;Nikita: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7169</id>
		<title>Участник:Nikita/Построение матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=7169"/>
		<updated>2016-10-14T09:06:31Z</updated>

		<summary type="html">&lt;p&gt;Nikita: Новая страница: «== Свойства и структура алгоритма ==   === Общее описание алгоритма ===  === Математическое опи…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita&amp;diff=7136</id>
		<title>Участник:Nikita</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Nikita&amp;diff=7136"/>
		<updated>2016-10-14T08:31:58Z</updated>

		<summary type="html">&lt;p&gt;Nikita: Создана пустая страница&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nikita</name></author>
	</entry>
</feed>