<?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=Y.ryabkova</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=Y.ryabkova"/>
	<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/Y.ryabkova"/>
	<updated>2026-10-22T23:25:19Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24795</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24795"/>
		<updated>2017-12-01T15:20:41Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В описанном алгоритме можно выделить два вычислительных ядра: первое соответствует операциям, выполняемым на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагах, а второе - последнему рекурсивному шагу с номером &amp;lt;math&amp;gt; m + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, можно составить из вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt; по формулам, данным в математическом описании алгоритма. Все эти вычисления представляют из себя сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Таким образом, первое вычислительное ядро алгоритма сводится к операциям сложения (вычитания) чисел на каждом рекурсивном шаге.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге, состоит из операций перемножения двух матриц по классическому алгоритму кубической сложности, основную часть которого составляют умножения чисел.&lt;br /&gt;
&lt;br /&gt;
Указанные операции составляют основную часть метода, причем с увеличением &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; доля операций первого вычислительного ядра будет расти, а доля операций второго - падать, и наоборот.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Штрассена состоит из &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов и может быть представлен в виде двух этапов. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; соответствует первым &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивным шагам, на каждом из которых можно выделить следующие три последовательные макрооперации:&lt;br /&gt;
&lt;br /&gt;
* вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* рекурсивный вызов для вычисления произведений &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, таким образом при переходе на следующий рекурсивный шаг задача размера &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt; сводится к семи задачам размера &amp;lt;math&amp;gt; \frac{k}{2} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* вычисление матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; соответствует последнему, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ому шагу алгоритма и выходу из рекурсии. Он представляет из себя вычисление произведения двух матриц матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Псевдокод простейшего варианта реализации последовательного алгоритма Штрассена, непосредственно вытекающего из его математического описания, может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute parts of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&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; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Так как они определены независимо друг от друга и хранятся в разных областях памяти, порядок их вычисления может быть произвольным, в том числе параллельным.&lt;br /&gt;
&lt;br /&gt;
* Выполнение семи рекурсивных вызовов функции &#039;&#039;Strassen&#039;&#039;, по одному для каждой тройки &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}&amp;lt;/math&amp;gt;. Порядок этих вызовов также может быть произвольным и параллельным.&lt;br /&gt;
&lt;br /&gt;
* Вычисление матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; из полученных после рекурсивных вызовов матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно, данная реализация требует большого количества дополнительной памяти, так как на каждом рекурсивном шаге необходимо одновременно хранить семь пар &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и семь результатов их умножения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант реализации последовательного алгоритма, позволяющий значительно сократить количество требуемой памяти:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
               compute part of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом рекурсивном шаге схема этой реализации представляет собой цикл по &amp;lt;math&amp;gt;i = 1,\dotsc,7&amp;lt;/math&amp;gt;, каждая итерация которого состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
* Вычисление &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ой пары матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Выполнение рекурсивного вызова функции &#039;&#039;Strassen&#039;&#039; для вычисления &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Обновление блоков матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; в соответствии с формулами алгоритма в зависимости от номера полученной после рекурсивного вызова матрицы &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Порядок итераций такого цикла может быть произвольным, но они должны выполняться строго последовательно. Такое требование позволяет выделить память всего для трёх &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц на каждом рекурсивном шаге: для одной пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и их произведения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;, и на каждой итерации цикла использовать одни и те же области памяти для хранения соответствующей тройки матриц.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Оба вышеописанных варианта реализации метода Штрассена требуют одинакового числа арифметических операций. В соответствии с макроструктурой алгоритма, рассмотрим каждый из его двух этапов отдельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; требует на первом рекурсивном шаге выполнения &amp;lt;math&amp;gt;18 \left( \frac{n}{2} \right)^2 &amp;lt;/math&amp;gt; сложений (вычитаний). При переходе на следующий рекурсивный шаг, задача будет сведена к семи аналогичным задачам, но вдвое меньшей размерности. Отсюда получаем, что на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-ом шаге потребуется &amp;lt;math&amp;gt;18 \cdot 7^{k-1} \left( \frac{n}{2^{k}} \right)^2 &amp;lt;/math&amp;gt; операций. Тогда всего на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагах потребуется следующее число сложений (вычитаний):&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 18 \left( \frac{n}{2} \right)^2 + 18 \cdot 7 \left( \frac{n}{4} \right)^2 + \dotsb + 18 \cdot 7^{m-1} \left( \frac{n}{2^{m}} \right)^2 = \frac{18}{4}n^{2}\left( 1 + \frac{7}{4} + \dotsb + \frac{7^{m-1}}{4^{m-1}}\right) = 6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Получена сложность первого этапа алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; включает в себя решение &amp;lt;math&amp;gt;7^m&amp;lt;/math&amp;gt; задач перемножения матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму, что требует &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений, всего &amp;lt;math&amp;gt;O\left(\frac{n^3}{2^{3m}}\right)&amp;lt;/math&amp;gt; арифметических операций.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всего&#039;&#039;&#039; последовательный алгоритм Штрассена требует:&lt;br /&gt;
* &amp;lt;math&amp;gt;6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) + 7^m\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений;&lt;br /&gt;
* &amp;lt;math&amp;gt;7^m\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
Как видно, сложность алгоритма зависит не только от порядка матрицы &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, но и от числа &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов первого этапа.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; m = L&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, то есть второй этап алгоритма сводится лишь к &amp;lt;math&amp;gt;7^L&amp;lt;/math&amp;gt; умножениям двух чисел, то сложность всего последовательного алгоритма равна &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 6n^2\left(\frac{7^{L}}{4^{L}} - 1 \right) + 7^L\left(\frac{n}{2^{L}}\right)^3 = 6n^2\left(\frac{7^{L}}{n^{2}} - 1 \right) + 7^L = 7 \cdot 7^{L} - 6n^2 = 7 n^{\log_2 7} - 6n^2 = O\left(n^{\log_2 7}\right) \approx O\left(n^{2.81}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, получена оценка сложности последовательного алгоритма Штрассена с максимально возможным числом &amp;lt;math&amp;gt;m = L&amp;lt;/math&amp;gt; рекурсивных шагов, соответствующая максимальной оценке сложности первого этапа алгоритма для произвольного &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Эта оценка асимптотически лучше оценки для классического метода перемножения матриц, требующего &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить роль правильного выбора параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Из полученных оценок видно, что при малых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; сложность алгоритма с уменьшением этого параметра будет стремиться к кубической сложности классического метода, а значит &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит выбирать относительно близким к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;. Однако, при &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, очень близких к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;, алгоритм на последних рекурсивных шагах будет применяться на матрицах малых размеров и требовать большего числа сложений, чем классический метод, и эта разница будет увеличиваться с уменьшением размера матрицы, что соответствует увеличению &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Отсюда следует, что существует некоторое оптимальное значение &amp;lt;math&amp;gt; m \in [1, L] &amp;lt;/math&amp;gt;, которое минимизирует число арифметических операций всего алгоритма и выбирается исходя из минимального размера матрицы, на которой описанный в первом этапе рекурсивный алгоритм будет эффективнее классического. Также при выборе &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит учитывать роль накладных расходов на реализацию рекурсии при малых размерах матриц.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма зависит от параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, то есть от заданного числа рекурсивных шагов. На рисунке изображен граф при &amp;lt;math&amp;gt; m = 1 &amp;lt;/math&amp;gt;, отражающий макроструктуру алгоритма (первая схема реализации последовательного алгоритма).&lt;br /&gt;
&lt;br /&gt;
[[File:Diagram.png|center|thumb|800px|Рисунок 1. Операции в последовательном алгоритме Штрассена при &#039;&#039;m = 1&#039;&#039;. Вершина &#039;&#039;mul()&#039;&#039; означает вызов классического метода умножения матриц.]]&lt;br /&gt;
&lt;br /&gt;
Как видно, на каждом уровне все операции могут выполняться параллельно и независимо друг от друга. При увеличении &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; на единицу, число уровней будет увеличиваться на два. Например, на данном графе это означает, что после вычисления всех &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; из входных данных &amp;lt;math&amp;gt; A, B&amp;lt;/math&amp;gt; будут производиться аналогичные вычисления для каждой пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Таким образом, новый уровень графа будет содержать &amp;lt;math&amp;gt;2 \cdot 49&amp;lt;/math&amp;gt; макроопераций. Из аналогичных соображений после вызовов &#039;&#039;mul()&#039;&#039; из возвращаемых значений надо будет сначала вычислить &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt; (семь независимых макроопераций), а уже из этих значений получить матрицу &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для реализации параллельного варианта алгоритма Штрассена небходимо последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; ярусов вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt;\frac{n}{2^k}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - номер яруса. Сложность этого этапа равна &amp;lt;math&amp;gt; \frac{n^2}{3}\left(1-\frac{1}{4^m}\right) &amp;lt;/math&amp;gt; операциям сложения.&lt;br /&gt;
* Ярус алгоритма классического умножения для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt;, что требует &amp;lt;math&amp;gt;\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений.&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; последовательных ярусов вычисления матрицы произведения &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; из полученных на предыдущем шаге матриц &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt;. Сам процесс вычисления этой матрицы можно разбить на четыре параллельных и независимых вычисления её блоков (исходя из формул математического описания алгоритма), поэтому сложность всего этапа составит &amp;lt;math&amp;gt; n^2 \left(1-\frac{1}{4^m}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность всего параллельного алгоритма составит &amp;lt;math&amp;gt;\frac{4 n^2}{3}\left(1-\frac{1}{4^m}\right) + \left(\frac{n}{2^{m}}\right)^3 + \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right) &amp;lt;/math&amp;gt; арифметических операций. При &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, близких к &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt;, эта оценка равна &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, то есть параллельная версия алгоритма Штрассена имеет квадратичную сложность.&lt;br /&gt;
&lt;br /&gt;
Основной ресурс конечного параллелизма алгоритма - независимое вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; на каждом рекурсивном шаге, причем с каждым шагом их количество возрастает в семь раз. Аналогично, при выходе из рекурсии, вычисление матриц-произведений из &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; производится независимо, причем вычисление каждой из них представимо в виде независимого обновления её четырех блоков.&lt;br /&gt;
&lt;br /&gt;
Более того, можно распараллелить вычисление каждой из матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;, так как оно сводится к операции сложения матриц, а значит к независимым операциям сложения элементов или блоков матрицы.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, где, в общем случае, &amp;lt;math&amp;gt; n = s \cdot 2^L&amp;lt;/math&amp;gt;. В данной реализации алгоритма в силу блочно-параллельного выполнения операции сложения двух матриц и особенностей их хранения, дополнительно требуется &amp;lt;math&amp;gt; n = s \cdot 7^{\left[\frac{\log_7p+1}{2}\right]} \cdot 2^m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - число процессов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2 + n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации алгоритма Штрассена. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; Суперкомпьютерного комплекса Московского университета.&lt;br /&gt;
Изменяемые параметры запуска реализации:&lt;br /&gt;
* число процессоров: 1, 7, 49, 343,&lt;br /&gt;
* размер матрицы: 14, 28, 56, 112, 224, 392, 448, 784, 896, 1568, 1792, 3136, 3584, 6272, 7168, 12544, 14336.&lt;br /&gt;
На следующем рисунке приведен график производительности реализованного алгоритма при фиксированной вычислительной сложности задачи.&lt;br /&gt;
&lt;br /&gt;
[[File:2nd.png|center|thumb|800px|Рисунок 2. График производительности алгоритма Штрассена]]&lt;br /&gt;
&lt;br /&gt;
Видно, что с увеличением числа процессоров производительность растет, однако отношение ее прироста к увеличению числа процессоров значительно меньше единицы.&lt;br /&gt;
&lt;br /&gt;
Следующий график показывает время работы алгоритма для различных входных параметров.&lt;br /&gt;
&lt;br /&gt;
[[File:Screenshot from 2017-11-30 23-04-13.png|center|thumb|800px|Рисунок 3. График времени работы алгоритма Штрассена]]&lt;br /&gt;
&lt;br /&gt;
Время работы программы резко возрастает на больших матрицах при малом числе процессоров.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24781</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24781"/>
		<updated>2017-12-01T00:12:13Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В описанном алгоритме можно выделить два вычислительных ядра: первое соответствует операциям, выполняемым на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагах, а второе - последнему рекурсивному шагу с номером &amp;lt;math&amp;gt; m + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, можно составить из вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt; по формулам, данным в математическом описании алгоритма. Все эти вычисления представляют из себя сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Таким образом, первое вычислительное ядро алгоритма сводится к операциям сложения (вычитания) чисел на каждом рекурсивном шаге.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге, состоит из операций перемножения двух матриц по классическому алгоритму кубической сложности, основную часть которого составляют умножения чисел.&lt;br /&gt;
&lt;br /&gt;
Указанные операции составляют основную часть метода, причем с увеличением &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; доля операций первого вычислительного ядра будет расти, а доля операций второго - падать, и наоборот.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Штрассена состоит из &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов и может быть представлен в виде двух этапов. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; соответствует первым &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивным шагам, на каждом из которых можно выделить следующие три последовательные макрооперации:&lt;br /&gt;
&lt;br /&gt;
* вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* рекурсивный вызов для вычисления произведений &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, таким образом при переходе на следующий рекурсивный шаг задача размера &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt; сводится к семи задачам размера &amp;lt;math&amp;gt; \frac{k}{2} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* вычисление матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; соответствует последнему, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ому шагу алгоритма и выходу из рекурсии. Он представляет из себя вычисление произведения двух матриц матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Псевдокод простейшего варианта реализации последовательного алгоритма Штрассена, непосредственно вытекающего из его математического описания, может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute parts of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&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; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Так как они определены независимо друг от друга и хранятся в разных областях памяти, порядок их вычисления может быть произвольным, в том числе параллельным.&lt;br /&gt;
&lt;br /&gt;
* Выполнение семи рекурсивных вызовов функции &#039;&#039;Strassen&#039;&#039;, по одному для каждой тройки &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}&amp;lt;/math&amp;gt;. Порядок этих вызовов также может быть произвольным и параллельным.&lt;br /&gt;
&lt;br /&gt;
* Вычисление матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; из полученных после рекурсивных вызовов матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно, данная реализация требует большого количества дополнительной памяти, так как на каждом рекурсивном шаге необходимо одновременно хранить семь пар &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и семь результатов их умножения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант реализации последовательного алгоритма, позволяющий значительно сократить количество требуемой памяти:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
               compute part of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом рекурсивном шаге схема этой реализации представляет собой цикл по &amp;lt;math&amp;gt;i = 1,\dotsc,7&amp;lt;/math&amp;gt;, каждая итерация которого состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
* Вычисление &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ой пары матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Выполнение рекурсивного вызова функции &#039;&#039;Strassen&#039;&#039; для вычисления &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Обновление блоков матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; в соответствии с формулами алгоритма в зависимости от номера полученной после рекурсивного вызова матрицы &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Порядок итераций такого цикла может быть произвольным, но они должны выполняться строго последовательно. Такое требование позволяет выделить память всего для трёх &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц на каждом рекурсивном шаге: для одной пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и их произведения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;, и на каждой итерации цикла использовать одни и те же области памяти для хранения соответствующей тройки матриц.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Оба вышеописанных варианта реализации метода Штрассена требуют одинакового числа арифметических операций. В соответствии с макроструктурой алгоритма, рассмотрим каждый из его двух этапов отдельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; требует на первом рекурсивном шаге выполнения &amp;lt;math&amp;gt;18 \left( \frac{n}{2} \right)^2 &amp;lt;/math&amp;gt; сложений (вычитаний). При переходе на следующий рекурсивный шаг, задача будет сведена к семи аналогичным задачам, но вдвое меньшей размерности. Отсюда получаем, что на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-ом шаге потребуется &amp;lt;math&amp;gt;18 \cdot 7^{k-1} \left( \frac{n}{2^{k}} \right)^2 &amp;lt;/math&amp;gt; операций. Тогда всего на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагах потребуется следующее число сложений (вычитаний):&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 18 \left( \frac{n}{2} \right)^2 + 18 \cdot 7 \left( \frac{n}{4} \right)^2 + \dotsb + 18 \cdot 7^{m-1} \left( \frac{n}{2^{m}} \right)^2 = \frac{18}{4}n^{2}\left( 1 + \frac{7}{4} + \dotsb + \frac{7^{m-1}}{4^{m-1}}\right) = 6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Получена сложность первого этапа алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; включает в себя решение &amp;lt;math&amp;gt;7^m&amp;lt;/math&amp;gt; задач перемножения матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму, что требует &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений, всего &amp;lt;math&amp;gt;O\left(\frac{n^3}{2^{3m}}\right)&amp;lt;/math&amp;gt; арифметических операций.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всего&#039;&#039;&#039; последовательный алгоритм Штрассена требует:&lt;br /&gt;
* &amp;lt;math&amp;gt;6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) + 7^m\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений;&lt;br /&gt;
* &amp;lt;math&amp;gt;7^m\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
Как видно, сложность алгоритма зависит не только от порядка матрицы &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, но и от числа &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов первого этапа.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; m = L&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, то есть второй этап алгоритма сводится лишь к &amp;lt;math&amp;gt;7^L&amp;lt;/math&amp;gt; умножениям двух чисел, то сложность всего последовательного алгоритма равна &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 6n^2\left(\frac{7^{L}}{4^{L}} - 1 \right) + 7^L\left(\frac{n}{2^{L}}\right)^3 = 6n^2\left(\frac{7^{L}}{n^{2}} - 1 \right) + 7^L = 7 \cdot 7^{L} - 6n^2 = 7 n^{\log_2 7} - 6n^2 = O\left(n^{\log_2 7}\right) \approx O\left(n^{2.81}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, получена оценка сложности последовательного алгоритма Штрассена с максимально возможным числом &amp;lt;math&amp;gt;m = L&amp;lt;/math&amp;gt; рекурсивных шагов, соответствующая максимальной оценке сложности первого этапа алгоритма для произвольного &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Эта оценка асимптотически лучше оценки для классического метода перемножения матриц, требующего &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить роль правильного выбора параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Из полученных оценок видно, что при малых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; сложность алгоритма с уменьшением этого параметра будет стремиться к кубической сложности классического метода, а значит &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит выбирать относительно близким к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;. Однако, при &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, очень близких к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;, алгоритм на последних рекурсивных шагах будет применяться на матрицах малых размеров и требовать большего числа сложений, чем классический метод, и эта разница будет увеличиваться с уменьшением размера матрицы, что соответствует увеличению &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Отсюда следует, что существует некоторое оптимальное значение &amp;lt;math&amp;gt; m \in [1, L] &amp;lt;/math&amp;gt;, которое минимизирует число арифметических операций всего алгоритма и выбирается исходя из минимального размера матрицы, на которой описанный в первом этапе рекурсивный алгоритм будет эффективнее классического. Также при выборе &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит учитывать роль накладных расходов на реализацию рекурсии при малых размерах матриц.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма зависит от параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, то есть от заданного числа рекурсивных шагов. На рисунке изображен граф при &amp;lt;math&amp;gt; m = 1 &amp;lt;/math&amp;gt;, отражающий макроструктуру алгоритма (первая схема реализации последовательного алгоритма).&lt;br /&gt;
&lt;br /&gt;
[[File:Diagram.png|center|thumb|800px|Рисунок 1. Операции в последовательном алгоритме Штрассена при &#039;&#039;m = 1&#039;&#039;. Вершина &#039;&#039;mul()&#039;&#039; означает вызов классического метода умножения матриц.]]&lt;br /&gt;
&lt;br /&gt;
Как видно, на каждом уровне все операции могут выполняться параллельно и независимо друг от друга. При увеличении &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; на единицу, число уровней будет увеличиваться на два. Например, на данном графе это означает, что после вычисления всех &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; из входных данных &amp;lt;math&amp;gt; A, B&amp;lt;/math&amp;gt; будут производиться аналогичные вычисления для каждой пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Таким образом, новый уровень графа будет содержать &amp;lt;math&amp;gt;2 \cdot 49&amp;lt;/math&amp;gt; макроопераций. Из аналогичных соображений после вызовов &#039;&#039;mul()&#039;&#039; из возвращаемых значений надо будет сначала вычислить &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt; (семь независимых макроопераций), а уже из этих значений получить матрицу &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для реализации параллельного варианта алгоритма Штрассена небходимо последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; ярусов вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt;\frac{n}{2^k}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - номер яруса. Сложность этого этапа равна &amp;lt;math&amp;gt; \frac{n^2}{3}\left(1-\frac{1}{4^m}\right) &amp;lt;/math&amp;gt; операциям сложения.&lt;br /&gt;
* Ярус алгоритма классического умножения для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt;, что требует &amp;lt;math&amp;gt;\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений.&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; последовательных ярусов вычисления матрицы произведения &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; из полученных на предыдущем шаге матриц &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt;. Сам процесс вычисления этой матрицы можно разбить на четыре параллельных и независимых вычисления её блоков (исходя из формул математического описания алгоритма), поэтому сложность всего этапа составит &amp;lt;math&amp;gt; n^2 \left(1-\frac{1}{4^m}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность всего параллельного алгоритма составит &amp;lt;math&amp;gt;\frac{4 n^2}{3}\left(1-\frac{1}{4^m}\right) + \left(\frac{n}{2^{m}}\right)^3 + \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right) &amp;lt;/math&amp;gt; арифметических операций. При &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, близких к &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt;, эта оценка равна &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, то есть параллельная версия алгоритма Штрассена имеет квадратичную сложность.&lt;br /&gt;
&lt;br /&gt;
Основной ресурс конечного параллелизма алгоритма - независимое вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; на каждом рекурсивном шаге, причем с каждым шагом их количество возрастает в семь раз. Аналогично, при выходе из рекурсии, вычисление матриц-произведений из &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; производится независимо, причем вычисление каждой из них представимо в виде независимого обновления её четырех блоков.&lt;br /&gt;
&lt;br /&gt;
Более того, можно распараллелить вычисление каждой из матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;, так как оно сводится к операции сложения матриц, а значит к независимым операциям сложения элементов или блоков матрицы.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, где, в общем случае, &amp;lt;math&amp;gt; n = s \cdot 2^L&amp;lt;/math&amp;gt;. В данной реализации алгоритма в силу блочно-параллельного выполнения операции сложения двух матриц и особенностей их хранения, дополнительно требуется &amp;lt;math&amp;gt; n = s \cdot 7^{\left[\frac{\log_7p+1}{2}\right]} \cdot 2^m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - число процессов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2 + n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации алгоритма Штрассена. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; Суперкомпьютерного комплекса Московского университета.&lt;br /&gt;
Изменяемые параметры запуска реализации:&lt;br /&gt;
* число процессоров: 1, 7, 49, 343,&lt;br /&gt;
* размер матрицы: 14, 28, 56, 112, 224, 392, 448, 784, 896, 1568, 1792, 3136, 3584, 6272, 7168, 12544, 14336.&lt;br /&gt;
На следующем рисунке приведен график производительности реализованного алгоритма в зависимости от числа процессоров при фиксированной вычислительной сложности задачи.&lt;br /&gt;
&lt;br /&gt;
[[File:2nd.png|center|thumb|800px|Рисунок 2. График сильной масштабируемости алгоритма Штрассена]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Сильная масштабируемость:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24739</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24739"/>
		<updated>2017-11-30T21:25:21Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В описанном алгоритме можно выделить два вычислительных ядра: первое соответствует операциям, выполняемым на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагах, а второе - последнему рекурсивному шагу с номером &amp;lt;math&amp;gt; m + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, можно составить из вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt; по формулам, данным в математическом описании алгоритма. Все эти вычисления представляют из себя сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Таким образом, первое вычислительное ядро алгоритма сводится к операциям сложения (вычитания) чисел на каждом рекурсивном шаге.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге, состоит из операций перемножения двух матриц по классическому алгоритму кубической сложности, основную часть которого составляют умножения чисел.&lt;br /&gt;
&lt;br /&gt;
Указанные операции составляют основную часть метода, причем с увеличением &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; доля операций первого вычислительного ядра будет расти, а доля операций второго - падать, и наоборот.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Штрассена состоит из &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов и может быть представлен в виде двух этапов. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; соответствует первым &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивным шагам, на каждом из которых можно выделить следующие три последовательные макрооперации:&lt;br /&gt;
&lt;br /&gt;
* вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* рекурсивный вызов для вычисления произведений &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, таким образом при переходе на следующий рекурсивный шаг задача размера &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt; сводится к семи задачам размера &amp;lt;math&amp;gt; \frac{k}{2} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* вычисление матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; соответствует последнему, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ому шагу алгоритма и выходу из рекурсии. Он представляет из себя вычисление произведения двух матриц матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Псевдокод простейшего варианта реализации последовательного алгоритма Штрассена, непосредственно вытекающего из его математического описания, может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute parts of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&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; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Так как они определены независимо друг от друга и хранятся в разных областях памяти, порядок их вычисления может быть произвольным, в том числе параллельным.&lt;br /&gt;
&lt;br /&gt;
* Выполнение семи рекурсивных вызовов функции &#039;&#039;Strassen&#039;&#039;, по одному для каждой тройки &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}&amp;lt;/math&amp;gt;. Порядок этих вызовов также может быть произвольным и параллельным.&lt;br /&gt;
&lt;br /&gt;
* Вычисление матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; из полученных после рекурсивных вызовов матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно, данная реализация требует большого количества дополнительной памяти, так как на каждом рекурсивном шаге необходимо одновременно хранить семь пар &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и семь результатов их умножения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант реализации последовательного алгоритма, позволяющий значительно сократить количество требуемой памяти:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
               compute part of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом рекурсивном шаге схема этой реализации представляет собой цикл по &amp;lt;math&amp;gt;i = 1,\dotsc,7&amp;lt;/math&amp;gt;, каждая итерация которого состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
* Вычисление &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ой пары матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Выполнение рекурсивного вызова функции &#039;&#039;Strassen&#039;&#039; для вычисления &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Обновление блоков матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; в соответствии с формулами алгоритма в зависимости от номера полученной после рекурсивного вызова матрицы &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Порядок итераций такого цикла может быть произвольным, но они должны выполняться строго последовательно. Такое требование позволяет выделить память всего для трёх &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц на каждом рекурсивном шаге: для одной пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и их произведения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;, и на каждой итерации цикла использовать одни и те же области памяти для хранения соответствующей тройки матриц.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Оба вышеописанных варианта реализации метода Штрассена требуют одинакового числа арифметических операций. В соответствии с макроструктурой алгоритма, рассмотрим каждый из его двух этапов отдельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; требует на первом рекурсивном шаге выполнения &amp;lt;math&amp;gt;18 \left( \frac{n}{2} \right)^2 &amp;lt;/math&amp;gt; сложений (вычитаний). При переходе на следующий рекурсивный шаг, задача будет сведена к семи аналогичным задачам, но вдвое меньшей размерности. Отсюда получаем, что на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-ом шаге потребуется &amp;lt;math&amp;gt;18 \cdot 7^{k-1} \left( \frac{n}{2^{k}} \right)^2 &amp;lt;/math&amp;gt; операций. Тогда всего на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагах потребуется следующее число сложений (вычитаний):&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 18 \left( \frac{n}{2} \right)^2 + 18 \cdot 7 \left( \frac{n}{4} \right)^2 + \dotsb + 18 \cdot 7^{m-1} \left( \frac{n}{2^{m}} \right)^2 = \frac{18}{4}n^{2}\left( 1 + \frac{7}{4} + \dotsb + \frac{7^{m-1}}{4^{m-1}}\right) = 6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Получена сложность первого этапа алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; включает в себя решение &amp;lt;math&amp;gt;7^m&amp;lt;/math&amp;gt; задач перемножения матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму, что требует &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений, всего &amp;lt;math&amp;gt;O\left(\frac{n^3}{2^{3m}}\right)&amp;lt;/math&amp;gt; арифметических операций.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всего&#039;&#039;&#039; последовательный алгоритм Штрассена требует:&lt;br /&gt;
* &amp;lt;math&amp;gt;6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) + 7^m\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений;&lt;br /&gt;
* &amp;lt;math&amp;gt;7^m\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
Как видно, сложность алгоритма зависит не только от порядка матрицы &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, но и от числа &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов первого этапа.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; m = L&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, то есть второй этап алгоритма сводится лишь к &amp;lt;math&amp;gt;7^L&amp;lt;/math&amp;gt; умножениям двух чисел, то сложность всего последовательного алгоритма равна &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 6n^2\left(\frac{7^{L}}{4^{L}} - 1 \right) + 7^L\left(\frac{n}{2^{L}}\right)^3 = 6n^2\left(\frac{7^{L}}{n^{2}} - 1 \right) + 7^L = 7 \cdot 7^{L} - 6n^2 = 7 n^{\log_2 7} - 6n^2 = O\left(n^{\log_2 7}\right) \approx O\left(n^{2.81}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, получена оценка сложности последовательного алгоритма Штрассена с максимально возможным числом &amp;lt;math&amp;gt;m = L&amp;lt;/math&amp;gt; рекурсивных шагов, соответствующая максимальной оценке сложности первого этапа алгоритма для произвольного &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Эта оценка асимптотически лучше оценки для классического метода перемножения матриц, требующего &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить роль правильного выбора параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Из полученных оценок видно, что при малых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; сложность алгоритма с уменьшением этого параметра будет стремиться к кубической сложности классического метода, а значит &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит выбирать относительно близким к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;. Однако, при &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, очень близких к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;, алгоритм на последних рекурсивных шагах будет применяться на матрицах малых размеров и требовать большего числа сложений, чем классический метод, и эта разница будет увеличиваться с уменьшением размера матрицы, что соответствует увеличению &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Отсюда следует, что существует некоторое оптимальное значение &amp;lt;math&amp;gt; m \in [1, L] &amp;lt;/math&amp;gt;, которое минимизирует число арифметических операций всего алгоритма и выбирается исходя из минимального размера матрицы, на которой описанный в первом этапе рекурсивный алгоритм будет эффективнее классического. Также при выборе &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит учитывать роль накладных расходов на реализацию рекурсии при малых размерах матриц.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма зависит от параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, то есть от заданного числа рекурсивных шагов. На рисунке изображен граф при &amp;lt;math&amp;gt; m = 1 &amp;lt;/math&amp;gt;, отражающий макроструктуру алгоритма (первая схема реализации последовательного алгоритма).&lt;br /&gt;
&lt;br /&gt;
[[File:Diagram.png|center|thumb|800px|Рисунок 1. Операции в последовательном алгоритме Штрассена при &#039;&#039;m = 1&#039;&#039;. Вершина &#039;&#039;mul()&#039;&#039; означает вызов классического метода умножения матриц.]]&lt;br /&gt;
&lt;br /&gt;
Как видно, на каждом уровне все операции могут выполняться параллельно и независимо друг от друга. При увеличении &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; на единицу, число уровней будет увеличиваться на два. Например, на данном графе это означает, что после вычисления всех &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; из входных данных &amp;lt;math&amp;gt; A, B&amp;lt;/math&amp;gt; будут производиться аналогичные вычисления для каждой пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Таким образом, новый уровень графа будет содержать &amp;lt;math&amp;gt;2 \cdot 49&amp;lt;/math&amp;gt; макроопераций. Из аналогичных соображений после вызовов &#039;&#039;mul()&#039;&#039; из возвращаемых значений надо будет сначала вычислить &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt; (семь независимых макроопераций), а уже из этих значений получить матрицу &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для реализации параллельного варианта алгоритма Штрассена небходимо последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; ярусов вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt;\frac{n}{2^k}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - номер яруса. Сложность этого этапа равна &amp;lt;math&amp;gt; \frac{n^2}{3}\left(1-\frac{1}{4^m}\right) &amp;lt;/math&amp;gt; операциям сложения.&lt;br /&gt;
* Ярус алгоритма классического умножения для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt;, что требует &amp;lt;math&amp;gt;\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений.&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; последовательных ярусов вычисления матрицы произведения &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; из полученных на предыдущем шаге матриц &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt;. Сам процесс вычисления этой матрицы можно разбить на четыре параллельных и независимых вычисления её блоков (исходя из формул математического описания алгоритма), поэтому сложность всего этапа составит &amp;lt;math&amp;gt; n^2 \left(1-\frac{1}{4^m}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность всего параллельного алгоритма составит &amp;lt;math&amp;gt;\frac{4 n^2}{3}\left(1-\frac{1}{4^m}\right) + \left(\frac{n}{2^{m}}\right)^3 + \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right) &amp;lt;/math&amp;gt; арифметических операций. При &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, близких к &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt;, эта оценка равна &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, то есть параллельная версия алгоритма Штрассена имеет квадратичную сложность.&lt;br /&gt;
&lt;br /&gt;
Основной ресурс конечного параллелизма алгоритма - независимое вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; на каждом рекурсивном шаге, причем с каждым шагом их количество возрастает в семь раз. Аналогично, при выходе из рекурсии, вычисление матриц-произведений из &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; производится независимо, причем вычисление каждой из них представимо в виде независимого обновления её четырех блоков.&lt;br /&gt;
&lt;br /&gt;
Более того, можно распараллелить вычисление каждой из матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;, так как оно сводится к операции сложения матриц, а значит к независимым операциям сложения элементов или блоков матрицы.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, где, в общем случае, &amp;lt;math&amp;gt; n = s \cdot 2^L&amp;lt;/math&amp;gt;. В данной реализации алгоритма в силу блочно-параллельного выполнения операции сложения двух матриц и особенностей их хранения, дополнительно требуется &amp;lt;math&amp;gt; n = s \cdot 7^{\left[\frac{\log_7p+1}{2}\right]} \cdot 2^m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - число процессов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2 + n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации алгоритма Штрассена. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; Суперкомпьютерного комплекса Московского университета.&lt;br /&gt;
Изменяемые параметры запуска реализации:&lt;br /&gt;
* число процессоров: 1, 7, 49, 343,&lt;br /&gt;
* размер матрицы: 14, 28, 56, 112, 224, 392, 448, 784, 896, 1568, 1792, 3136, 3584, 6272, 7168, 12544, 14336.&lt;br /&gt;
На следующих рисунках приведен график времени работы реализованного алгоритма в зависимости от изменяемых параметров.&lt;br /&gt;
&lt;br /&gt;
[[File:Screenshot_from_2017-11-30_23-04-13.png|center|thumb|800px|Рисунок 2. ]]&lt;br /&gt;
[[File:Screenshot_from_2017-11-30_23-07-00.png|center|thumb|800px|Рисунок 3. ]]&lt;br /&gt;
[[File:Screenshot_from_2017-11-30_23-05-23.png|center|thumb|800px|Рисунок 4. ]]&lt;br /&gt;
&lt;br /&gt;
На графике видно, что при маленьком числе процессов алгоритм сильно теряет эффективность на больших матрицах.&lt;br /&gt;
&lt;br /&gt;
Исследуем сильную и слабую масштабируемость алгоритма.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Сильная масштабируемость.&#039;&#039;&#039;:&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24684</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24684"/>
		<updated>2017-11-30T17:54:37Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Свойства и структура алгоритмов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В описанном алгоритме можно выделить два вычислительных ядра: первое соответствует операциям, выполняемым на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагах, а второе - последнему рекурсивному шагу с номером &amp;lt;math&amp;gt; m + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, можно составить из вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt; по формулам, данным в математическом описании алгоритма. Все эти вычисления представляют из себя сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Таким образом, первое вычислительное ядро алгоритма сводится к операциям сложения (вычитания) чисел на каждом рекурсивном шаге.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге, состоит из операций перемножения двух матриц по классическому алгоритму кубической сложности, основную часть которого составляют умножения чисел.&lt;br /&gt;
&lt;br /&gt;
Указанные операции составляют основную часть метода, причем с увеличением &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; доля операций первого вычислительного ядра будет расти, а доля операций второго - падать, и наоборот.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Штрассена состоит из &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов и может быть представлен в виде двух этапов. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; соответствует первым &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивным шагам, на каждом из которых можно выделить следующие три последовательные макрооперации:&lt;br /&gt;
&lt;br /&gt;
* вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* рекурсивный вызов для вычисления произведений &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, таким образом при переходе на следующий рекурсивный шаг задача размера &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt; сводится к семи задачам размера &amp;lt;math&amp;gt; \frac{k}{2} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* вычисление матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; соответствует последнему, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ому шагу алгоритма и выходу из рекурсии. Он представляет из себя вычисление произведения двух матриц матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Псевдокод простейшего варианта реализации последовательного алгоритма Штрассена, непосредственно вытекающего из его математического описания, может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute parts of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&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; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Так как они определены независимо друг от друга и хранятся в разных областях памяти, порядок их вычисления может быть произвольным, в том числе параллельным.&lt;br /&gt;
&lt;br /&gt;
* Выполнение семи рекурсивных вызовов функции &#039;&#039;Strassen&#039;&#039;, по одному для каждой тройки &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}&amp;lt;/math&amp;gt;. Порядок этих вызовов также может быть произвольным и параллельным.&lt;br /&gt;
&lt;br /&gt;
* Вычисление матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; из полученных после рекурсивных вызовов матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно, данная реализация требует большого количества дополнительной памяти, так как на каждом рекурсивном шаге необходимо одновременно хранить семь пар &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и семь результатов их умножения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант реализации последовательного алгоритма, позволяющий значительно сократить количество требуемой памяти:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
               compute part of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом рекурсивном шаге схема этой реализации представляет собой цикл по &amp;lt;math&amp;gt;i = 1,\dotsc,7&amp;lt;/math&amp;gt;, каждая итерация которого состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
* Вычисление &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ой пары матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Выполнение рекурсивного вызова функции &#039;&#039;Strassen&#039;&#039; для вычисления &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Обновление блоков матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; в соответствии с формулами алгоритма в зависимости от номера полученной после рекурсивного вызова матрицы &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Порядок итераций такого цикла может быть произвольным, но они должны выполняться строго последовательно. Такое требование позволяет выделить память всего для трёх &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц на каждом рекурсивном шаге: для одной пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и их произведения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;, и на каждой итерации цикла использовать одни и те же области памяти для хранения соответствующей тройки матриц.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Оба вышеописанных варианта реализации метода Штрассена требуют одинакового числа арифметических операций. В соответствии с макроструктурой алгоритма, рассмотрим каждый из его двух этапов отдельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; требует на первом рекурсивном шаге выполнения &amp;lt;math&amp;gt;18 \left( \frac{n}{2} \right)^2 &amp;lt;/math&amp;gt; сложений (вычитаний). При переходе на следующий рекурсивный шаг, задача будет сведена к семи аналогичным задачам, но вдвое меньшей размерности. Отсюда получаем, что на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-ом шаге потребуется &amp;lt;math&amp;gt;18 \cdot 7^{k-1} \left( \frac{n}{2^{k}} \right)^2 &amp;lt;/math&amp;gt; операций. Тогда всего на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагах потребуется следующее число сложений (вычитаний):&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 18 \left( \frac{n}{2} \right)^2 + 18 \cdot 7 \left( \frac{n}{4} \right)^2 + \dotsb + 18 \cdot 7^{m-1} \left( \frac{n}{2^{m}} \right)^2 = \frac{18}{4}n^{2}\left( 1 + \frac{7}{4} + \dotsb + \frac{7^{m-1}}{4^{m-1}}\right) = 6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Получена сложность первого этапа алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; включает в себя решение &amp;lt;math&amp;gt;7^m&amp;lt;/math&amp;gt; задач перемножения матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму, что требует &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений, всего &amp;lt;math&amp;gt;O\left(\frac{n^3}{2^{3m}}\right)&amp;lt;/math&amp;gt; арифметических операций.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всего&#039;&#039;&#039; последовательный алгоритм Штрассена требует:&lt;br /&gt;
* &amp;lt;math&amp;gt;6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) + 7^m\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений;&lt;br /&gt;
* &amp;lt;math&amp;gt;7^m\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
Как видно, сложность алгоритма зависит не только от порядка матрицы &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, но и от числа &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов первого этапа.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; m = L&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, то есть второй этап алгоритма сводится лишь к &amp;lt;math&amp;gt;7^L&amp;lt;/math&amp;gt; умножениям двух чисел, то сложность всего последовательного алгоритма равна &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 6n^2\left(\frac{7^{L}}{4^{L}} - 1 \right) + 7^L\left(\frac{n}{2^{L}}\right)^3 = 6n^2\left(\frac{7^{L}}{n^{2}} - 1 \right) + 7^L = 7 \cdot 7^{L} - 6n^2 = 7 n^{\log_2 7} - 6n^2 = O\left(n^{\log_2 7}\right) \approx O\left(n^{2.81}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, получена оценка сложности последовательного алгоритма Штрассена с максимально возможным числом &amp;lt;math&amp;gt;m = L&amp;lt;/math&amp;gt; рекурсивных шагов, соответствующая максимальной оценке сложности первого этапа алгоритма для произвольного &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Эта оценка асимптотически лучше оценки для классического метода перемножения матриц, требующего &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить роль правильного выбора параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Из полученных оценок видно, что при малых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; сложность алгоритма с уменьшением этого параметра будет стремиться к кубической сложности классического метода, а значит &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит выбирать относительно близким к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;. Однако, при &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, очень близких к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;, алгоритм на последних рекурсивных шагах будет применяться на матрицах малых размеров и требовать большего числа сложений, чем классический метод, и эта разница будет увеличиваться с уменьшением размера матрицы, что соответствует увеличению &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Отсюда следует, что существует некоторое оптимальное значение &amp;lt;math&amp;gt; m \in [1, L] &amp;lt;/math&amp;gt;, которое минимизирует число арифметических операций всего алгоритма и выбирается исходя из минимального размера матрицы, на которой описанный в первом этапе рекурсивный алгоритм будет эффективнее классического. Также при выборе &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит учитывать роль накладных расходов на реализацию рекурсии при малых размерах матриц.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма зависит от параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, то есть от заданного числа рекурсивных шагов. На рисунке изображен граф при &amp;lt;math&amp;gt; m = 1 &amp;lt;/math&amp;gt;, отражающий макроструктуру алгоритма (первая схема реализации последовательного алгоритма).&lt;br /&gt;
&lt;br /&gt;
[[File:Diagram.png|center|thumb|800px|Рисунок 1. Операции в последовательном алгоритме Штрассена при &#039;&#039;m = 1&#039;&#039;. Вершина &#039;&#039;mul()&#039;&#039; означает вызов классического метода умножения матриц.]]&lt;br /&gt;
&lt;br /&gt;
Как видно, на каждом уровне все операции могут выполняться параллельно и независимо друг от друга. При увеличении &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; на единицу, число уровней будет увеличиваться на два. Например, на данном графе это означает, что после вычисления всех &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; из входных данных &amp;lt;math&amp;gt; A, B&amp;lt;/math&amp;gt; будут производиться аналогичные вычисления для каждой пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Таким образом, новый уровень графа будет содержать &amp;lt;math&amp;gt;2 \cdot 49&amp;lt;/math&amp;gt; макроопераций. Из аналогичных соображений после вызовов &#039;&#039;mul()&#039;&#039; из возвращаемых значений надо будет сначала вычислить &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt; (семь независимых макроопераций), а уже из этих значений получить матрицу &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для реализации параллельного варианта алгоритма Штрассена небходимо последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; ярусов вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt;\frac{n}{2^k}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - номер яруса. Сложность этого этапа равна &amp;lt;math&amp;gt; \frac{n^2}{3}\left(1-\frac{1}{4^m}\right) &amp;lt;/math&amp;gt; операциям сложения.&lt;br /&gt;
* Ярус алгоритма классического умножения для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt;, что требует &amp;lt;math&amp;gt;\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений.&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; последовательных ярусов вычисления матрицы произведения &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; из полученных на предыдущем шаге матриц &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt;. Сам процесс вычисления этой матрицы можно разбить на четыре параллельных и независимых вычисления её блоков (исходя из формул математического описания алгоритма), поэтому сложность всего этапа составит &amp;lt;math&amp;gt; n^2 \left(1-\frac{1}{4^m}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность всего параллельного алгоритма составит &amp;lt;math&amp;gt;\frac{4 n^2}{3}\left(1-\frac{1}{4^m}\right) + \left(\frac{n}{2^{m}}\right)^3 + \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right) &amp;lt;/math&amp;gt; арифметических операций. При &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, близких к &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt;, эта оценка равна &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, то есть параллельная версия алгоритма Штрассена имеет квадратичную сложность.&lt;br /&gt;
&lt;br /&gt;
Основной ресурс конечного параллелизма алгоритма - независимое вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; на каждом рекурсивном шаге, причем с каждым шагом их количество возрастает в семь раз. Аналогично, при выходе из рекурсии, вычисление матриц-произведений из &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; производится независимо, причем вычисление каждой из них представимо в виде независимого обновления её четырех блоков.&lt;br /&gt;
&lt;br /&gt;
Более того, можно распараллелить вычисление каждой из матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;, так как оно сводится к операции сложения матриц, а значит к независимым операциям сложения элементов или блоков матрицы.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, где, в общем случае, &amp;lt;math&amp;gt; n = s \cdot 2^L&amp;lt;/math&amp;gt;. В данной реализации алгоритма в силу блочно-параллельного выполнения операции сложения двух матриц и особенностей их хранения, дополнительно требуется &amp;lt;math&amp;gt; n = s \cdot 7^{\left[\frac{\log_7p+1}{2}\right]} \cdot 2^m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - число процессов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2 + n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24672</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24672"/>
		<updated>2017-11-30T16:17:14Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Свойства и структура алгоритмов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В описанном алгоритме можно выделить два вычислительных ядра: первое соответствует операциям, выполняемым на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагах, а второе - последнему рекурсивному шагу с номером &amp;lt;math&amp;gt; m + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, можно составить из вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt; по формулам, данным в математическом описании алгоритма. Все эти вычисления представляют из себя сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Таким образом, первое вычислительное ядро алгоритма сводится к операциям сложения (вычитания) чисел на каждом рекурсивном шаге.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге, состоит из операций перемножения двух матриц по классическому алгоритму кубической сложности, основную часть которого составляют умножения чисел.&lt;br /&gt;
&lt;br /&gt;
Указанные операции составляют основную часть метода, причем с увеличением &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; доля операций первого вычислительного ядра будет расти, а доля операций второго - падать, и наоборот.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Штрассена состоит из &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов и может быть представлен в виде двух этапов. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; соответствует первым &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивным шагам, на каждом из которых можно выделить следующие три последовательные макрооперации:&lt;br /&gt;
&lt;br /&gt;
* вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* рекурсивный вызов для вычисления произведений &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, таким образом при переходе на следующий рекурсивный шаг задача размера &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt; сводится к семи задачам размера &amp;lt;math&amp;gt; \frac{k}{2} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* вычисление матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; соответствует последнему, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ому шагу алгоритма и выходу из рекурсии. Он представляет из себя вычисление произведения двух матриц матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Псевдокод простейшего варианта реализации последовательного алгоритма Штрассена, непосредственно вытекающего из его математического описания, может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute parts of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&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; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Так как они определены независимо друг от друга и хранятся в разных областях памяти, порядок их вычисления может быть произвольным, в том числе параллельным.&lt;br /&gt;
&lt;br /&gt;
* Выполнение семи рекурсивных вызовов функции &#039;&#039;Strassen&#039;&#039;, по одному для каждой тройки &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}&amp;lt;/math&amp;gt;. Порядок этих вызовов также может быть произвольным и параллельным.&lt;br /&gt;
&lt;br /&gt;
* Вычисление матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; из полученных после рекурсивных вызовов матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно, данная реализация требует большого количества дополнительной памяти, так как на каждом рекурсивном шаге необходимо одновременно хранить семь пар &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и семь результатов их умножения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант реализации последовательного алгоритма, позволяющий значительно сократить количество требуемой памяти:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
               compute part of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом рекурсивном шаге схема этой реализации представляет собой цикл по &amp;lt;math&amp;gt;i = 1,\dotsc,7&amp;lt;/math&amp;gt;, каждая итерация которого состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
* Вычисление &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ой пары матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Выполнение рекурсивного вызова функции &#039;&#039;Strassen&#039;&#039; для вычисления &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Обновление блоков матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; в соответствии с формулами алгоритма в зависимости от номера полученной после рекурсивного вызова матрицы &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Порядок итераций такого цикла может быть произвольным, но они должны выполняться строго последовательно. Такое требование позволяет выделить память всего для трёх &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц на каждом рекурсивном шаге: для одной пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и их произведения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;, и на каждой итерации цикла использовать одни и те же области памяти для хранения соответствующей тройки матриц.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Оба вышеописанных варианта реализации метода Штрассена требуют одинакового числа арифметических операций. В соответствии с макроструктурой алгоритма, рассмотрим каждый из его двух этапов отдельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; требует на первом рекурсивном шаге выполнения &amp;lt;math&amp;gt;18 \left( \frac{n}{2} \right)^2 &amp;lt;/math&amp;gt; сложений (вычитаний). При переходе на следующий рекурсивный шаг, задача будет сведена к семи аналогичным задачам, но вдвое меньшей размерности. Отсюда получаем, что на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-ом шаге потребуется &amp;lt;math&amp;gt;18 \cdot 7^{k-1} \left( \frac{n}{2^{k}} \right)^2 &amp;lt;/math&amp;gt; операций. Тогда всего на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагах потребуется следующее число сложений (вычитаний):&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 18 \left( \frac{n}{2} \right)^2 + 18 \cdot 7 \left( \frac{n}{4} \right)^2 + \dotsb + 18 \cdot 7^{m-1} \left( \frac{n}{2^{m}} \right)^2 = \frac{18}{4}n^{2}\left( 1 + \frac{7}{4} + \dotsb + \frac{7^{m-1}}{4^{m-1}}\right) = 6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Получена сложность первого этапа алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; включает в себя решение &amp;lt;math&amp;gt;7^m&amp;lt;/math&amp;gt; задач перемножения матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму, что требует &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений, всего &amp;lt;math&amp;gt;O\left(\frac{n^3}{2^{3m}}\right)&amp;lt;/math&amp;gt; арифметических операций.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всего&#039;&#039;&#039; последовательный алгоритм Штрассена требует:&lt;br /&gt;
* &amp;lt;math&amp;gt;6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) + 7^m\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений;&lt;br /&gt;
* &amp;lt;math&amp;gt;7^m\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
Как видно, сложность алгоритма зависит не только от порядка матрицы &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, но и от числа &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов первого этапа.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; m = L&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, то есть второй этап алгоритма сводится лишь к &amp;lt;math&amp;gt;7^L&amp;lt;/math&amp;gt; умножениям двух чисел, то сложность всего последовательного алгоритма равна &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 6n^2\left(\frac{7^{L}}{4^{L}} - 1 \right) + 7^L\left(\frac{n}{2^{L}}\right)^3 = 6n^2\left(\frac{7^{L}}{n^{2}} - 1 \right) + 7^L = 7 \cdot 7^{L} - 6n^2 = 7 n^{\log_2 7} - 6n^2 = O\left(n^{\log_2 7}\right) \approx O\left(n^{2.81}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, получена оценка сложности последовательного алгоритма Штрассена с максимально возможным числом &amp;lt;math&amp;gt;m = L&amp;lt;/math&amp;gt; рекурсивных шагов, соответствующая максимальной оценке сложности первого этапа алгоритма для произвольного &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Эта оценка асимптотически лучше оценки для классического метода перемножения матриц, требующего &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить роль правильного выбора параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Из полученных оценок видно, что при малых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; сложность алгоритма с уменьшением этого параметра будет стремиться к кубической сложности классического метода, а значит &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит выбирать относительно близким к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;. Однако, при &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, очень близких к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;, алгоритм на последних рекурсивных шагах будет применяться на матрицах малых размеров и требовать большего числа сложений, чем классический метод, и эта разница будет увеличиваться с уменьшением размера матрицы, что соответствует увеличению &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Отсюда следует, что существует некоторое оптимальное значение &amp;lt;math&amp;gt; m \in [1, L] &amp;lt;/math&amp;gt;, которое минимизирует число арифметических операций всего алгоритма и выбирается исходя из минимального размера матрицы, на которой описанный в первом этапе рекурсивный алгоритм будет эффективнее классического. Также при выборе &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит учитывать роль накладных расходов на реализацию рекурсии при малых размерах матриц.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма зависит от параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, то есть от заданного числа рекурсивных шагов. На рисунке изображен граф при &amp;lt;math&amp;gt; m = 1 &amp;lt;/math&amp;gt;, отражающий макроструктуру алгоритма (первая схема реализации последовательного алгоритма).&lt;br /&gt;
&lt;br /&gt;
[[File:Diagram.png|center|thumb|800px|Рисунок 1. Операции в последовательном алгоритме Штрассена при &#039;&#039;m = 1&#039;&#039;. Вершина &#039;&#039;mul()&#039;&#039; означает вызов классического метода умножения матриц.]]&lt;br /&gt;
&lt;br /&gt;
Как видно, на каждом уровне все операции могут выполняться параллельно и независимо друг от друга. При увеличении &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; на единицу, число уровней будет увеличиваться на два. Например, на данном графе это означает, что после вычисления всех &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; из входных данных &amp;lt;math&amp;gt; A, B&amp;lt;/math&amp;gt; будут производиться аналогичные вычисления для каждой пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Таким образом, новый уровень графа будет содержать &amp;lt;math&amp;gt;2 \cdot 49&amp;lt;/math&amp;gt; макроопераций. Из аналогичных соображений после вызовов &#039;&#039;mul()&#039;&#039; из возвращаемых значений надо будет сначала вычислить &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt; (семь независимых макроопераций), а уже из этих значений получить матрицу &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24597</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24597"/>
		<updated>2017-11-30T08:05:57Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Свойства и структура алгоритмов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В описанном алгоритме можно выделить два вычислительных ядра: первое соответствует операциям, выполняемым на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагах, а второе - последнему рекурсивному шагу с номером &amp;lt;math&amp;gt; m + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, можно составить из вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt; по формулам, данным в математическом описании алгоритма. Все эти вычисления представляют из себя сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Таким образом, первое вычислительное ядро алгоритма сводится к операциям сложения (вычитания) чисел на каждом рекурсивном шаге.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге, состоит из операций перемножения двух матриц по классическому алгоритму кубической сложности, основную часть которого составляют умножения чисел.&lt;br /&gt;
&lt;br /&gt;
Указанные операции составляют основную часть метода, причем с увеличением &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; доля операций первого вычислительного ядра будет расти, а доля операций второго - падать, и наоборот.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Штрассена состоит из &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов и может быть представлен в виде двух этапов. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; соответствует первым &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивным шагам, на каждом из которых можно выделить следующие три последовательные макрооперации:&lt;br /&gt;
&lt;br /&gt;
* вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* рекурсивный вызов для вычисления произведений &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, таким образом при переходе на следующий рекурсивный шаг задача размера &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt; сводится к семи задачам размера &amp;lt;math&amp;gt; \frac{k}{2} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* вычисление матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; соответствует последнему, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ому шагу алгоритма и выходу из рекурсии. Он представляет из себя вычисление произведения двух матриц матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Псевдокод простейшего варианта реализации последовательного алгоритма Штрассена, непосредственно вытекающего из его математического описания, может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute parts of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&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; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Так как они определены независимо друг от друга и хранятся в разных областях памяти, порядок их вычисления может быть произвольным, в том числе параллельным.&lt;br /&gt;
&lt;br /&gt;
* Выполнение семи рекурсивных вызовов функции &#039;&#039;Strassen&#039;&#039;, по одному для каждой тройки &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}&amp;lt;/math&amp;gt;. Порядок этих вызовов также может быть произвольным и параллельным.&lt;br /&gt;
&lt;br /&gt;
* Вычисление матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; из полученных после рекурсивных вызовов матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно, данная реализация требует большого количества дополнительной памяти, так как на каждом рекурсивном шаге необходимо одновременно хранить семь пар &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и семь результатов их умножения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант реализации последовательного алгоритма, позволяющий значительно сократить количество требуемой памяти:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
               compute part of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом рекурсивном шаге схема этой реализации представляет собой цикл по &amp;lt;math&amp;gt;i = 1,\dotsc,7&amp;lt;/math&amp;gt;, каждая итерация которого состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
* Вычисление &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ой пары матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Выполнение рекурсивного вызова функции &#039;&#039;Strassen&#039;&#039; для вычисления &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Обновление блоков матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; в соответствии с формулами алгоритма в зависимости от номера полученной после рекурсивного вызова матрицы &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Порядок итераций такого цикла может быть произвольным, но они должны выполняться строго последовательно. Такое требование позволяет выделить память всего для трёх &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц на каждом рекурсивном шаге: для одной пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и их произведения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;, и на каждой итерации цикла использовать одни и те же области памяти для хранения соответствующей тройки матриц.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Оба вышеописанных варианта реализации метода Штрассена требуют одинакового числа арифметических операций. В соответствии с макроструктурой алгоритма, рассмотрим каждый из его двух этапов отдельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; требует на первом рекурсивном шаге выполнения &amp;lt;math&amp;gt;18 \left( \frac{n}{2} \right)^2 &amp;lt;/math&amp;gt; сложений (вычитаний). При переходе на следующий рекурсивный шаг, задача будет сведена к семи аналогичным задачам, но вдвое меньшей размерности. Отсюда получаем, что на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-ом шаге потребуется &amp;lt;math&amp;gt;18 \cdot 7^{k-1} \left( \frac{n}{2^{k}} \right)^2 &amp;lt;/math&amp;gt; операций. Тогда всего на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагах потребуется следующее число сложений (вычитаний):&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 18 \left( \frac{n}{2} \right)^2 + 18 \cdot 7 \left( \frac{n}{4} \right)^2 + \dotsb + 18 \cdot 7^{m-1} \left( \frac{n}{2^{m}} \right)^2 = \frac{18}{4}n^{2}\left( 1 + \frac{7}{4} + \dotsb + \frac{7^{m-1}}{4^{m-1}}\right) = 6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Получена сложность первого этапа алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; включает в себя решение &amp;lt;math&amp;gt;7^m&amp;lt;/math&amp;gt; задач перемножения матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму, что требует &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений, всего &amp;lt;math&amp;gt;O\left(\frac{n^3}{2^{3m}}\right)&amp;lt;/math&amp;gt; арифметических операций.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всего&#039;&#039;&#039; последовательный алгоритм Штрассена требует:&lt;br /&gt;
* &amp;lt;math&amp;gt;6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) + 7^m\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений;&lt;br /&gt;
* &amp;lt;math&amp;gt;7^m\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
Как видно, сложность алгоритма зависит не только от порядка матрицы &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, но и от числа &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов первого этапа.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; m = L&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, то есть второй этап алгоритма сводится лишь к &amp;lt;math&amp;gt;7^L&amp;lt;/math&amp;gt; умножениям двух чисел, то сложность всего последовательного алгоритма равна &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 6n^2\left(\frac{7^{L}}{4^{L}} - 1 \right) + 7^L\left(\frac{n}{2^{L}}\right)^3 = 6n^2\left(\frac{7^{L}}{n^{2}} - 1 \right) + 7^L = 7 \cdot 7^{L} - 6n^2 = 7 n^{\log_2 7} - 6n^2 = O\left(n^{\log_2 7}\right) \approx O\left(n^{2.81}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, получена оценка сложности последовательного алгоритма Штрассена с максимально возможным числом &amp;lt;math&amp;gt;m = L&amp;lt;/math&amp;gt; рекурсивных шагов, соответствующая максимальной оценке сложности первого этапа алгоритма для произвольного &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Эта оценка асимптотически лучше оценки для классического метода перемножения матриц, требующего &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить роль правильного выбора параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Из полученных оценок видно, что при малых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; сложность алгоритма с уменьшением этого параметра будет стремиться к кубической сложности классического метода, а значит &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит выбирать относительно близким к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;. Однако, при &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, очень близких к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;, алгоритм на последних рекурсивных шагах будет применяться на матрицах малых размеров и требовать большего числа сложений, чем классический метод, и эта разница будет увеличиваться с уменьшением размера матрицы, что соответствует увеличению &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Отсюда следует, что существует некоторое оптимальное значение &amp;lt;math&amp;gt; m \in [1, L] &amp;lt;/math&amp;gt;, которое минимизирует число арифметических операций всего алгоритма и выбирается исходя из минимального размера матрицы, на которой описанный в первом этапе рекурсивный алгоритм будет эффективнее классического. Также при выборе &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит учитывать роль накладных расходов на реализацию рекурсии при малых размерах матриц.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24596</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24596"/>
		<updated>2017-11-30T07:52:36Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Свойства и структура алгоритмов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В описанном алгоритме можно выделить два вычислительных ядра: первое соответствует операциям, выполняемым на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагах, а второе - последнему рекурсивному шагу с номером &amp;lt;math&amp;gt; m + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, можно составить из вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt; по формулам, данным в математическом описании алгоритма. Все эти вычисления представляют из себя сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Таким образом, первое вычислительное ядро алгоритма сводится к операциям сложения (вычитания) чисел на каждом рекурсивном шаге.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге, состоит из операций перемножения двух матриц по классическому алгоритму кубической сложности, основную часть которого составляют умножения чисел.&lt;br /&gt;
&lt;br /&gt;
Указанные операции составляют основную часть метода, причем с увеличением &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; доля операций первого вычислительного ядра будет расти, а доля операций второго - падать, и наоборот.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Штрассена состоит из &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов и может быть представлен в виде двух этапов. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; соответствует первым &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивным шагам, на каждом из которых можно выделить следующие три последовательные макрооперации:&lt;br /&gt;
&lt;br /&gt;
* вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* рекурсивный вызов для вычисления произведений &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, таким образом при переходе на следующий рекурсивный шаг задача размера &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt; сводится к семи задачам размера &amp;lt;math&amp;gt; \frac{k}{2} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* вычисление матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; соответствует последнему, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ому шагу алгоритма и выходу из рекурсии. Он представляет из себя вычисление произведения двух матриц матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Псевдокод простейшего варианта реализации последовательного алгоритма Штрассена, непосредственно вытекающего из его математического описания, может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute parts of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&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; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Так как они определены независимо друг от друга и хранятся в разных областях памяти, порядок их вычисления может быть произвольным, в том числе параллельным.&lt;br /&gt;
&lt;br /&gt;
* Выполнение семи рекурсивных вызовов функции &#039;&#039;Strassen&#039;&#039;, по одному для каждой тройки &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}&amp;lt;/math&amp;gt;. Порядок этих вызовов также может быть произвольным и параллельным.&lt;br /&gt;
&lt;br /&gt;
* Вычисление матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; из полученных после рекурсивных вызовов матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно, данная реализация требует большого количества дополнительной памяти, так как на каждом рекурсивном шаге необходимо одновременно хранить семь пар &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и семь результатов их умножения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант реализации последовательного алгоритма, позволяющий значительно сократить количество требуемой памяти:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! переход к классическому алгоритму умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
               compute part of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом рекурсивном шаге схема этой реализации представляет собой цикл по &amp;lt;math&amp;gt;i = 1,\dotsc,7&amp;lt;/math&amp;gt;, каждая итерация которого состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
* Вычисление &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ой пары матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Выполнение рекурсивного вызова функции &#039;&#039;Strassen&#039;&#039; для вычисления &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Обновление блоков матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; в соответствии с формулами алгоритма в зависимости от номера полученной после рекурсивного вызова матрицы &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Порядок итераций такого цикла может быть произвольным, но они должны выполняться строго последовательно. Такое требование позволяет выделить память всего для трёх &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц на каждом рекурсивном шаге: для одной пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и их произведения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;, и на каждой итерации цикла использовать одни и те же области памяти для хранения соответствующей тройки матриц.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Оба вышеописанных варианта реализации метода Штрассена требуют одинакового числа арифметических операций. В соответствии с макроструктурой алгоритма, рассмотрим каждый из его двух этапов отдельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; требует на первом рекурсивном шаге выполнения &amp;lt;math&amp;gt;18 \left( \frac{n}{2} \right)^2 &amp;lt;/math&amp;gt; сложений (вычитаний). При переходе на следующий рекурсивный шаг, задача будет сведена к семи аналогичным задачам, но вдвое меньшей размерности. Отсюда получаем, что на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-ом шаге потребуется &amp;lt;math&amp;gt;18 \cdot 7^{k-1} \left( \frac{n}{2^{k}} \right)^2 &amp;lt;/math&amp;gt; операций. Тогда всего на первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагах потребуется следующее число сложений (вычитаний):&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 18 \left( \frac{n}{2} \right)^2 + 18 \cdot 7 \left( \frac{n}{4} \right)^2 + \dotsb + 18 \cdot 7^{m-1} \left( \frac{n}{2^{m}} \right)^2 = \frac{18}{4}n^{2}\left( 1 + \frac{7}{4} + \dotsb + \frac{7^{m-1}}{4^{m-1}}\right) = 6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Получена сложность первого этапа алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039; включает в себя решение &amp;lt;math&amp;gt;7^m&amp;lt;/math&amp;gt; задач перемножения матриц порядка &amp;lt;math&amp;gt; \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму, что требует &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;7^m \left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений, всего &amp;lt;math&amp;gt;O\left(\frac{n^3}{2^{3m}}\right)&amp;lt;/math&amp;gt; арифметических операций.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всего&#039;&#039;&#039; последовательный алгоритм Штрассена требует:&lt;br /&gt;
* &amp;lt;math&amp;gt;6n^2\left(\frac{7^{m}}{4^{m}} - 1 \right) + 7^m\left(\frac{n}{2^{m}}\right)^2\left(\frac{n}{2^{m}}-1\right)&amp;lt;/math&amp;gt; сложений;&lt;br /&gt;
* &amp;lt;math&amp;gt;7^m\left(\frac{n}{2^{m}}\right)^3&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
Как видно, сложность алгоритма зависит не только от порядка матрицы &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;, но и от числа &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов первого этапа.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; m = L&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, то есть второй этап алгоритма сводится лишь к &amp;lt;math&amp;gt;7^L&amp;lt;/math&amp;gt; умножениям двух чисел, то сложность всего последовательного алгоритма равна &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; 6n^2\left(\frac{7^{L}}{4^{L}} - 1 \right) + 7^L\left(\frac{n}{2^{L}}\right)^3 = 6n^2\left(\frac{7^{L}}{n^{2}} - 1 \right) + 7^L = 7 \cdot 7^{L} - 6n^2 = 7 n^{\log_2 7} - 6n^2 = O\left(n^{\log_2 7}\right) \approx O\left(n^{2.81}\right) &amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, получена оценка сложности последовательного алгоритма Штрассена с максимально возможным числом &amp;lt;math&amp;gt;m = L&amp;lt;/math&amp;gt; рекурсивных шагов, соответствующая максимальной оценке сложности первого этапа алгоритма для произвольного &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Эта оценка асимптотически лучше оценки для классического метода перемножения матриц, требующего &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить роль правильного выбора параметра &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Из полученных оценок видно, что при малых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; сложность алгоритма с уменьшением этого параметра будет стремиться к кубической сложности классического метода, однако при &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, очень близких к &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt;, алгоритм будет требовать большего числа сложений, чем классический метод, которое будет увеличиваться с ростом &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Отсюда следует, что существует некоторое оптимальное значение &amp;lt;math&amp;gt; m \in [1, L] &amp;lt;/math&amp;gt;, которое минимизирует число арифметических операций всего алгоритма. Также при выборе &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; стоит учитывать роль накладных расходов на реализацию рекурсии при малых размерах матриц.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24595</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24595"/>
		<updated>2017-11-30T04:50:59Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, можно составить из вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt; по формулам, данным в математическом описании алгоритма. Все эти вычисления представляют из себя &amp;lt;math&amp;gt; 18 &amp;lt;/math&amp;gt; операций сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Таким образом, вычислительное ядро алгоритма сводится к &amp;lt;math&amp;gt; 18 &amp;lt;/math&amp;gt; операциям сложения (вычитания) матриц или к &amp;lt;math&amp;gt; 18 k^2 &amp;lt;/math&amp;gt; операциям сложения (вычитания) чисел на каждом рекурсивном шаге.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Штрассена состоит из &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов и может быть представлен в виде двух этапов. &lt;br /&gt;
&lt;br /&gt;
Первый этап соответствует первым &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивным шагам, на каждом из которых можно выделить следующие три последовательные макрооперации:&lt;br /&gt;
1. вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;;&lt;br /&gt;
2. рекурсивный вызов для вычисления произведений &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, таким образом при переходе на следующий рекурсивный шаг задача размера &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt; сводится к семи задачам размера &amp;lt;math&amp;gt; \frac{k}{2} &amp;lt;/math&amp;gt;;&lt;br /&gt;
3. вычисление матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Второй этап соответствует последнему, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ому шагу алгоритма и выходу из рекурсии. Он представляет из себя вычисление произведения двух матриц матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{n_{m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Псевдокод простейшего варианта реализации последовательного алгоритма Штрассена, непосредственно вытекающего из его математического описания, может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
        call Strassen(a, b, c, n, m)&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! классический алгоритм умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute parts of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждом рекурсивном шаге эта схема состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
1. Вычисление семи пар матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Так как они определены независимо друг от друга, порядок их вычисления может быть произвольным, в том числе параллельным.&lt;br /&gt;
&lt;br /&gt;
2. Выполнение семи рекурсивных вызовов функции Strassen -- по одному для каждой тройки &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}&amp;lt;/math&amp;gt;. Порядок этих вызовов также может быть произвольным и параллельным.&lt;br /&gt;
&lt;br /&gt;
3. Вычисление матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; из полученных после рекурсивных вызовов матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно, данная реализация требует большого количества дополнительной памяти, так как на каждом рекурсивном шаге требуется одновременно хранить семь пар &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и семь результатов их произведений &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант реализации последовательного алгоритма, позволяющий значительно сократить количество требуемой памяти:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
        call Strassen(a, b, c, n, m)&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! классический алгоритм умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
               compute part of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом рекурсивном шаге схема этой реализации представляет собой цикл по &amp;lt;math&amp;gt;i = 1,\dotsc,7&amp;lt;/math&amp;gt;, каждая итерация которого состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
1. Вычисление &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ой пары матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Выполнение рекурсивного вызова функции Strassen для вычисления &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Изменение значений блоков матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; в соответствии с формулами алгоритма в зависимости от номера полученной после рекурсивного вызова матрицы &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Порядок итераций такого цикла может быть произвольным, но они должны выполняться строго последовательно. Такое требование позволяет выделить память всего для трёх &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц на каждом рекурсивном шаге: для одной пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и результата их произведения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;, и на каждой итерации цикла использовать одни и те же области памяти для хранения соответствующей тройки матриц.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24594</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24594"/>
		<updated>2017-11-30T04:47:23Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Свойства и структура алгоритмов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, можно составить из вычисления матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt; по формулам, данным в математическом описании алгоритма. Все эти вычисления представляют из себя &amp;lt;math&amp;gt; 18 &amp;lt;/math&amp;gt; операций сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Таким образом, вычислительное ядро алгоритма сводится к &amp;lt;math&amp;gt; 18 &amp;lt;/math&amp;gt; операциям сложения (вычитания) матриц или к &amp;lt;math&amp;gt; 18 k^2 &amp;lt;/math&amp;gt; операциям сложения (вычитания) чисел на каждом рекурсивном шаге.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Штрассена состоит из &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов и может быть представлен в виде двух этапов. &lt;br /&gt;
&lt;br /&gt;
Первый этап соответствует первым &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивным шагам, на каждом из которых можно выделить следующие три последовательные макрооперации:&lt;br /&gt;
1. вычисление матриц &amp;lt;math&amp;gt; S_{i}, T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;;&lt;br /&gt;
2. рекурсивный вызов для вычисления произведений &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1, 7} &amp;lt;/math&amp;gt;, таким образом при переходе на следующий рекурсивный шаг задача размера &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt; сводится к семи задачам размера &amp;lt;math&amp;gt; \frac{k}{2} &amp;lt;/math&amp;gt;;&lt;br /&gt;
3. вычисление матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Второй этап соответствует последнему, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ому шагу алгоритма и выходу из рекурсии. Он представляет из себя вычисление произведения двух матриц матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{n_{m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Псевдокод простейшего варианта реализации последовательного алгоритма Штрассена, непосредственно вытекающего из его математического описания, может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
        call Strassen(a, b, c, n, m)&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! классический алгоритм умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
           end do&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute parts of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждом рекурсивном шаге эта схема состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
1. Вычисление семи пар матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;. Так как они определены независимо друг от друга, порядок их вычисления может быть произвольным, в том числе параллельным.&lt;br /&gt;
&lt;br /&gt;
2. Выполнение семи рекурсивных вызовов функции Strassen -- по одному для каждой тройки &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}&amp;lt;/math&amp;gt;. Порядок этих вызовов также может быть произвольным и параллельным.&lt;br /&gt;
&lt;br /&gt;
3. Вычисление матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; из полученных после рекурсивных вызовов матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно, данная реализация требует большого количества дополнительной памяти, так как на каждом рекурсивном шаге требуется одновременно хранить семь пар &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и семь результатов их произведений &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант реализации последовательного алгоритма, позволяющий значительно сократить количество требуемой памяти:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
        call Strassen(a, b, c, n, m)&lt;br /&gt;
&lt;br /&gt;
	Strassen(A, B, C, k, m) ! C = A * B&lt;br /&gt;
           if (m == 0) call mul(A, B, C, k) ! классический алгоритм умножения матриц&lt;br /&gt;
           do i = 1, 7&lt;br /&gt;
               compute S[i], T[i] from A and B&lt;br /&gt;
               call Strassen(S[i], T[i], alpha[i], k/2, m-1)&lt;br /&gt;
               compute part of C from alpha[i]&lt;br /&gt;
           end do&lt;br /&gt;
        end Strassen&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом рекурсивном шаге схема этой реализации представляет собой цикл по &amp;lt;math&amp;gt;i = 1,\dotsc,7&amp;lt;/math&amp;gt;, каждая итерация которого состоит из трёх последовательных этапов:&lt;br /&gt;
&lt;br /&gt;
1. Вычисление &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ой пары матриц &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Выполнение рекурсивного вызова функции Strassen для вычисления &amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Изменение значений блоков матрицы &amp;lt;math&amp;gt; С &amp;lt;/math&amp;gt; в соответствии с формулами алгоритма в зависимости от номера полученной после рекурсивного вызова матрицы &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Порядок итераций такого цикла может быть произвольным, но они должны выполняться строго последовательно. Такая структура позволяет выделить память всего для трёх &amp;lt;math&amp;gt;\frac{k}{2}\times\frac{k}{2}&amp;lt;/math&amp;gt;-матриц на каждом рекурсивном шаге: для одной пары &amp;lt;math&amp;gt; S_{i}, T_{i} &amp;lt;/math&amp;gt; и результата их произведения &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt;, и на каждой итерации цикла использовать одни и те же области памяти для хранения соответствующей тройки матриц.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24593</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24593"/>
		<updated>2017-11-30T01:25:57Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, представляет из себя вычисление матриц &amp;lt;math&amp;gt; S_{i}, \: T_{i}, i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1, 7} &amp;lt;/math&amp;gt;. Все эти вычисления сводятся к &amp;lt;math&amp;gt; 18 &amp;lt;/math&amp;gt; операциям сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24592</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24592"/>
		<updated>2017-11-30T01:25:02Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта алгоритма Штрассена на каждом рекурсивном шаге, кроме последнего, представляет из себя вычисление матриц &amp;lt;math&amp;gt; S_{i}, \: T_{i}, i = \overline{1, 7} &amp;lt;/math&amp;gt;, и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1, 7} &amp;lt;/math&amp;gt;. Все эти вычисления сводятся к &amp;lt;math&amp;gt; 18 &amp;lt;/math&amp;gt; поэлементным операциям сложения (вычитания) матриц порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24591</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24591"/>
		<updated>2017-11-30T00:58:28Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта метода Штрассена для первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов может быть составлено из операций сложения (вычитания) двух матриц некоторого порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно. Все вычисления на каждом из первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов, а именно вычисление матриц &amp;lt;math&amp;gt; S_{i}, \: T_{i} &amp;lt;/math&amp;gt; и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i} &amp;lt;/math&amp;gt; сводятся к &amp;lt;math&amp;gt;18&amp;lt;/math&amp;gt; таким операциям.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге представляет из себя вычисление произведения двух матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}}. &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24590</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24590"/>
		<updated>2017-11-30T00:53:38Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта метода Штрассена для первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов может быть составлено из &amp;lt;math&amp;gt; 18 &amp;lt;/math&amp;gt; операций сложения (вычитания) двух матриц некоторого порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^{s_m}} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; r_{ij} = p_{ij} + q_{ij}, \: i,j = \overline{1, k} &amp;lt;/math&amp;gt;.&lt;br /&gt;
В таком виде могут быть представлены все вычисления на каждом из первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов, а именно вычисление матриц &amp;lt;math&amp;gt; S_{i}, \: T_{i}, \: i = \overline{1,7} &amp;lt;/math&amp;gt; и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1,7} &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге представляет из себя вычисление произведения двух матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}}. &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24589</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24589"/>
		<updated>2017-11-30T00:52:05Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Свойства и структура алгоритмов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательного варианта метода Штрассена для первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов может быть составлено из &amp;lt;math&amp;gt; 18 &amp;lt;/math&amp;gt; операций сложения (вычитания) двух матриц некоторого порядка &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, зависящего от номера шага &amp;lt;math&amp;gt; s_m &amp;lt;/math&amp;gt; следующим образом: &amp;lt;math&amp;gt; k = \frac{n}{2^s_m} &amp;lt;/math&amp;gt;. Операции выполняются поэлементно: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; r_{ij} = p_{ij} + q_{ij}, \: i,j = \overline{1, k} &amp;lt;/math&amp;gt;.&lt;br /&gt;
В таком виде могут быть представлены все вычисления на каждом из первых &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; рекурсивных шагов, а именно вычисление матриц &amp;lt;math&amp;gt; S_{i}, \: T_{i}, \: i = \overline{1,7} &amp;lt;/math&amp;gt; и блоков матрицы &amp;lt;math&amp;gt; C &amp;lt;/math&amp;gt; из матриц &amp;lt;math&amp;gt; \alpha_{i}, \: i = \overline{1,7} &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма на последнем, &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt;-ом рекурсивном шаге представляет из себя вычисление произведения двух матриц порядка &amp;lt;math&amp;gt; n_{m} = \frac{n}{2^{m}} &amp;lt;/math&amp;gt; по классическому алгоритму: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{ij} = \sum_{k = 1}^{n_{m}} a_{ik} b_{kj}, \: i,j = \overline{1, n_{m}}. &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24588</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24588"/>
		<updated>2017-11-29T23:23:53Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть весь процесс перемножения матриц требует &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; рекурсивных шагов, где первые &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; шагов выполняются в соответствии с алгоритмом Штрассена, а на последнем шаге используется классический алгоритм умножения матриц.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24587</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24587"/>
		<updated>2017-11-29T23:13:12Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений. Именно такой вариант метода рассматривается в данном описании. Пусть &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; -- число рекурсивных шагов, выполненных по алгоритму Штрассена, тогда переход на классический алгоритм происходит на шаге &amp;lt;math&amp;gt; m + 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;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24586</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24586"/>
		<updated>2017-11-29T23:11:29Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений. Именно такой вариант метода рассматривается в данном описании, где &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; обозначает число рекурсивных шагов, выполненных по алгоритму Штрассена.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24584</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24584"/>
		<updated>2017-11-29T22:53:21Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \begin{align*}&lt;br /&gt;
 &amp;amp;S_{1} = A_{11} + A_{22},   &amp;amp;   &amp;amp;T_{1} = B_{11} + B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{2} = A_{21} + A_{22},   &amp;amp;   &amp;amp;T_{2} = B_{11},          \\&lt;br /&gt;
 &amp;amp;S_{3} = A_{11},            &amp;amp;   &amp;amp;T_{3} = B_{12} − B_{22}, \\&lt;br /&gt;
 &amp;amp;S_{4} = A_{22},            &amp;amp;   &amp;amp;T_{4} = B_{21} − B_{11}, \\&lt;br /&gt;
 &amp;amp;S_{5} = A_{11} + A_{12},   &amp;amp;   &amp;amp;T_{5} = B_{22},          \\&lt;br /&gt;
 &amp;amp;S_{6} = A_{21} − A_{11},   &amp;amp;   &amp;amp;T_{6} = B_{11} + B_{12}, \\&lt;br /&gt;
 &amp;amp;S_{7} = A_{12} − A_{22},   &amp;amp;   &amp;amp;T_{7} = B_{21} + B_{22},          &lt;br /&gt;
\end{align*} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24582</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24582"/>
		<updated>2017-11-29T22:43:01Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; S_{1} = A_{11} + A_{22}, \: T_{1} = B_{11} + B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; S_{2} = A_{21} + A_{22}, \: T_{2} = B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; S_{3} = A_{11}, \: T_{3} = B_{12} − B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; S_{4} = A_{22}, \: T_{4} = B_{21} − B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; S_{5} = A_{11} + A_{12}, \: T_{5} = B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; S_{6} = A_{21} − A_{11}, \: T_{6} = B_{11} + B_{12}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; S_{7} = A_{12} − A_{22}, \: T_{7} = B_{21} + B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{i} = S_{i} \cdot T_{i}, \: i = \overline{1,7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24581</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24581"/>
		<updated>2017-11-29T22:29:59Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, \: L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24580</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=24580"/>
		<updated>2017-11-29T22:28:15Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;. Аналогичным образом можно не ограничивая общности предположить, что &amp;lt;math&amp;gt; n = s \cdot 2^L, L, s \in \mathbb{N} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Всего потребуется &amp;lt;math&amp;gt;\log_{2}n&amp;lt;/math&amp;gt; рекурсивных шагов, на последнем из которых задача будет сведена к перемножению двух чисел. Однако, на практике разумно продолжать рекурсивный процесс до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым (или, в случае &amp;lt;math&amp;gt; n = s \cdot 2^L &amp;lt;/math&amp;gt;, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кратно 2), а далее использовать классический способ умножения матриц. Именно такой вариант метода рассматривается в данном описании. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом умножения матриц, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23053</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23053"/>
		<updated>2017-10-16T20:39:05Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Рекурсивный процесс продолжается до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23052</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23052"/>
		<updated>2017-10-16T20:36:54Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Свойства и структура алгоритмов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом&amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Рекурсивный процесс продолжается до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23051</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23051"/>
		<updated>2017-10-16T20:35:39Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений &amp;lt;ref&amp;gt;Тыртышников Е.Е. Матричный анализ и линейная алгебра. М.: 2004-2005.&amp;lt;/ref&amp;gt;, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Рекурсивный процесс продолжается до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23050</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23050"/>
		<updated>2017-10-16T20:27:35Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Рекурсивный процесс продолжается до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23049</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23049"/>
		<updated>2017-10-16T20:23:47Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt;, также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Рекурсивный процесс продолжается до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23048</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23048"/>
		<updated>2017-10-16T20:21:00Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB = &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt; также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Рекурсивный процесс продолжается до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23047</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23047"/>
		<updated>2017-10-16T20:18:22Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Свойства и структура алгоритмов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы  A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB = &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt; также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Рекурсивный процесс продолжается до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23046</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23046"/>
		<updated>2017-10-16T20:15:27Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Итак, пусть &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Рассмотрим матрицы  A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt; 2 \times 2 &amp;lt;/math&amp;gt;-матрицы с квадратными блоками порядка &amp;lt;math&amp;gt;frac{n}{2}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
A = \begin{bmatrix}&lt;br /&gt;
  A_{11} &amp;amp; A_{12} \\&lt;br /&gt;
  A_{21} &amp;amp; A_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B_{11} &amp;amp; B_{12} \\&lt;br /&gt;
  B_{21} &amp;amp; B_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Их произведение &amp;lt;math&amp;gt; C = AB = &amp;lt;/math&amp;gt;, согласно алгоритму Штрассена, вычисляется следующим образом:&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (A_{21} + A_{22})B_{11}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = A_{11}(B_{12} − B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = A_{22}(B_{21} − B_{11}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (A_{11} + A_{12})B_{22}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{12} = \alpha_{3} + \alpha_{5}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{21} = \alpha_{2} + \alpha_{4}, &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, &amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
C = \begin{bmatrix}&lt;br /&gt;
  C_{11} &amp;amp; C_{12} \\&lt;br /&gt;
  C_{21} &amp;amp; C_{22}&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
Для вычисления матриц &amp;lt;math&amp;gt; \alpha_{i}, i = \overline{1,7} &amp;lt;/math&amp;gt; также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка &amp;lt;math&amp;gt; \frac{n}{2} &amp;lt;/math&amp;gt;. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; к задаче размера &amp;lt;math&amp;gt;\frac{k}{2}&amp;lt;/math&amp;gt;. Рекурсивный процесс продолжается до тех пор, пока &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23045</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23045"/>
		<updated>2017-10-16T19:52:16Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Итак, &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{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;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23044</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23044"/>
		<updated>2017-10-16T19:51:34Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, то можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Итак, &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{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;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23043</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23043"/>
		<updated>2017-10-16T19:51:14Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц со сложностью &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, то можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Итак, &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{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;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23042</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23042"/>
		<updated>2017-10-16T19:50:01Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц, в котором &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt; операций. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, то можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Итак, &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{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;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23041</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23041"/>
		<updated>2017-10-16T19:48:18Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц &amp;lt;math&amp;gt;(O(n^3))&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, то можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Итак, &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{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;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23040</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23040"/>
		<updated>2017-10-16T19:47:36Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt; (далее будет показано, что данное предположение не нарушает общности рассуждений), и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц &amp;lt;math&amp;gt;(O(n^3))&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, то можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Итак, &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{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;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23039</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23039"/>
		<updated>2017-10-16T19:47:02Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt;, и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц &amp;lt;math&amp;gt;(O(n^3))&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, то можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Итак, &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{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;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23038</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23038"/>
		<updated>2017-10-16T19:46:23Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt;, и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц &amp;lt;math&amp;gt;(O(n^3))&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt; A, B \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt; — заданные плотные матрицы. Вычислим матрицу &amp;lt;math&amp;gt; C \in \mathbb{R}^{n \times n} &amp;lt;/math&amp;gt;, такую, что  &amp;lt;math&amp;gt; C = AB &amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Для удобства будем полагать, что &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{N} &amp;lt;/math&amp;gt;. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и &amp;lt;math&amp;gt; n &amp;lt; 2^L &amp;lt;/math&amp;gt;, то можно рассмотреть квадратные матрицы &amp;lt;math&amp;gt;\tilde{A}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B}&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt; 2^L &amp;lt;/math&amp;gt; следующего вида: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{A} = \begin{bmatrix}&lt;br /&gt;
  A &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
\tilde{B} =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  B &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
то есть матрицы, полученные из матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; дополнением их нулевыми строками и столбцами в позициях &amp;lt;math&amp;gt; i = \overline{n+1, 2^L} &amp;lt;/math&amp;gt; до размера &amp;lt;math&amp;gt; 2^L \times 2^L &amp;lt;/math&amp;gt;. По правилу перемножения блочных матриц получим: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; \tilde{C} = \tilde{A}\tilde{B} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  AB &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  C &amp;amp; 0 \\&lt;br /&gt;
  0 &amp;amp; 0&lt;br /&gt;
\end{bmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, решая задачу для матриц &amp;lt;math&amp;gt; \tilde{A} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\tilde{B} &amp;lt;/math&amp;gt;, получим решение исходной задачи умножения матриц &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; B &amp;lt;/math&amp;gt; как левый верхний &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-блок матрицы &amp;lt;math&amp;gt;\tilde{C}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Итак, &amp;lt;math&amp;gt; n = 2^L, L \in \mathbb{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;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23037</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23037"/>
		<updated>2017-10-16T19:20:59Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. &amp;lt;br&amp;gt;&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt;, и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц &amp;lt;math&amp;gt;(O(n^3))&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23036</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=23036"/>
		<updated>2017-10-16T19:18:26Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Штрассена&#039;&#039;&#039;, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; над полем вещественных чисел &amp;lt;math&amp;gt;\mathbb{R}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
В 1965 году Штрассен нашел способ умножения двух матриц размера &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. Рассмотрим этот способ подробнее: пусть &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - произвольные квадратные матрицы порядка &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt;: &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt; A = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  a_{11} &amp;amp; a_{12} \\&lt;br /&gt;
  a_{21} &amp;amp; a_{22}&lt;br /&gt;
\end{bmatrix}, \: \:&lt;br /&gt;
B =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  b_{11} &amp;amp; b_{12} \\&lt;br /&gt;
  b_{21} &amp;amp; b_{22}&lt;br /&gt;
\end{bmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
тогда их произведение &amp;lt;br&amp;gt; &lt;br /&gt;
: &amp;lt;math&amp;gt; C = AB = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  c_{11} &amp;amp; c_{12} \\&lt;br /&gt;
  c_{21} &amp;amp; c_{22}&lt;br /&gt;
\end{bmatrix}&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
может быть получено последовательными вычислениями по следующим формулам:&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{1} = (a_{11} + a_{22})(b_{11} + b_{22}) &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{2} = (a_{21} + a_{22})b_{11} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{3} = a_{11}(b_{12} − b_{22}) &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{4} = a_{22}(b_{21} − b_{11}) &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{5} = (a_{11} + a_{12})b_{22} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{6} = (a_{21} − a_{11})(b_{11} + b_{12}) &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; \alpha_{7} = (a_{12} − a_{22})(b_{21} + b_{22}) &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{12} = \alpha_{3} + \alpha_{5} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{21} = \alpha_{2} + \alpha_{4} &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; c_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что &amp;lt;math&amp;gt;n = 2^L&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; L \in \mathbb{N} &amp;lt;/math&amp;gt;, и будем рассматривать матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; как блочные &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матрицы с размером блоков &amp;lt;math&amp;gt;\frac{n}{2} \times \frac{n}{2} &amp;lt;/math&amp;gt;. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц не используется коммутативность, этот метод подходит и для умножения блочных &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц. Таким образом, от задачи умножения &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt;-матриц с семью умножениями можно перейти к задаче умножения &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;-матриц, требующей не более чем &amp;lt;math&amp;gt; O(7n^{\log_27}) &amp;lt;/math&amp;gt; операций, что асимптотически лучше классического способа умножения матриц &amp;lt;math&amp;gt;(O(n^3))&amp;lt;/math&amp;gt;. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=22966</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=22966"/>
		<updated>2017-10-12T17:02:36Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:Y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;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>Y.ryabkova</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:Y.ryabkova&amp;diff=22965</id>
		<title>Участник:Y.ryabkova</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:Y.ryabkova&amp;diff=22965"/>
		<updated>2017-10-12T17:01:44Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: Создана пустая страница&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=22964</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=22964"/>
		<updated>2017-10-12T17:00:22Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Основные авторы описания: [[Участник:y.ryabkova|Ю.В.Рябкова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;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>Y.ryabkova</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=22963</id>
		<title>Участник:Y.ryabkova/Умножение матриц методом Штрассена</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:Y.ryabkova/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D0%A8%D1%82%D1%80%D0%B0%D1%81%D1%81%D0%B5%D0%BD%D0%B0&amp;diff=22963"/>
		<updated>2017-10-12T16:44:03Z</updated>

		<summary type="html">&lt;p&gt;Y.ryabkova: Новая страница: « = Свойства и структура алгоритмов =  == Общее описание алгоритма ==  == Математическое описа…»&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>Y.ryabkova</name></author>
	</entry>
</feed>