Участник:Y.ryabkova/Умножение матриц методом Штрассена: различия между версиями

Материал из Алговики
Перейти к навигации Перейти к поиску
Строка 6: Строка 6:
== Общее описание алгоритма ==
== Общее описание алгоритма ==


'''Алгоритм Штрассена''', описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка <math>n</math> над полем вещественных чисел <math>\mathbb{R}</math>. <br>
'''Алгоритм Штрассена''', описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка <math>n</math> над полем вещественных чисел <math>\mathbb{R}</math>.
В 1965 году Штрассен нашел способ умножения двух матриц размера <math>2 \times 2</math> с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел. <br>
 
В 1965 году Штрассен нашел способ умножения двух матриц размера <math>2 \times 2</math> с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.
 
Теперь предположим, что <math>n = 2^L</math>, <math> L \in \mathbb{N} </math> (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы <math>A</math> и <math>B</math> как блочные <math>2 \times 2</math>-матрицы с размером блоков <math>\frac{n}{2} \times \frac{n}{2} </math>. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения <math>2 \times 2</math>-матриц не используется коммутативность, этот метод подходит и для умножения блочных <math>2 \times 2</math>-матриц. Таким образом, от задачи умножения <math>2 \times 2</math>-матриц с семью умножениями можно перейти к задаче умножения <math>n \times n</math>-матриц, требующей не более чем <math> O(7n^{\log_27}) </math> операций, что асимптотически лучше классического способа умножения матриц сложностью <math>O(n^3)</math>. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.
Теперь предположим, что <math>n = 2^L</math>, <math> L \in \mathbb{N} </math> (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы <math>A</math> и <math>B</math> как блочные <math>2 \times 2</math>-матрицы с размером блоков <math>\frac{n}{2} \times \frac{n}{2} </math>. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения <math>2 \times 2</math>-матриц не используется коммутативность, этот метод подходит и для умножения блочных <math>2 \times 2</math>-матриц. Таким образом, от задачи умножения <math>2 \times 2</math>-матриц с семью умножениями можно перейти к задаче умножения <math>n \times n</math>-матриц, требующей не более чем <math> O(7n^{\log_27}) </math> операций, что асимптотически лучше классического способа умножения матриц сложностью <math>O(n^3)</math>. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.


== Математическое описание алгоритма ==
== Математическое описание алгоритма ==


Пусть <math> A, B \in \mathbb{R}^{n \times n} </math> — заданные плотные матрицы. Вычислим матрицу <math> C \in \mathbb{R}^{n \times n} </math>, такую, что  <math> C = AB </math>. <br>
Пусть <math> A, B \in \mathbb{R}^{n \times n} </math> — заданные плотные матрицы. Вычислим матрицу <math> C \in \mathbb{R}^{n \times n} </math>, такую, что  <math> C = AB </math>.
 
Для удобства будем полагать, что <math> n = 2^L, L \in \mathbb{N} </math>. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и <math> n < 2^L </math>, можно рассмотреть квадратные матрицы <math>\tilde{A}</math> и <math>\tilde{B}</math> порядка <math> 2^L </math> следующего вида: <br>
Для удобства будем полагать, что <math> n = 2^L, L \in \mathbb{N} </math>. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и <math> n < 2^L </math>, можно рассмотреть квадратные матрицы <math>\tilde{A}</math> и <math>\tilde{B}</math> порядка <math> 2^L </math> следующего вида: <br>
: <math> \tilde{A} = \begin{bmatrix}
: <math> \tilde{A} = \begin{bmatrix}
Строка 35: Строка 38:
\end{bmatrix}.
\end{bmatrix}.
</math>
</math>
Таким образом, решая задачу для матриц <math> \tilde{A} </math> и <math>\tilde{B} </math>, получим решение исходной задачи умножения матриц <math> A </math> и <math> B </math> как левый верхний <math>n \times n</math>-блок матрицы <math>\tilde{C}</math>.<br>
Таким образом, решая задачу для матриц <math> \tilde{A} </math> и <math>\tilde{B} </math>, получим решение исходной задачи умножения матриц <math> A </math> и <math> B </math> как левый верхний <math>n \times n</math>-блок матрицы <math>\tilde{C}</math>.
 
Итак, пусть <math> n = 2^L, L \in \mathbb{N} </math>. Рассмотрим матрицы  A </math> и <math> B </math> как блочные <math> 2 \times 2 </math>-матрицы с квадратными блоками порядка <math>frac{n}{2}</math>:<br>
Итак, пусть <math> n = 2^L, L \in \mathbb{N} </math>. Рассмотрим матрицы  A </math> и <math> B </math> как блочные <math> 2 \times 2 </math>-матрицы с квадратными блоками порядка <math>frac{n}{2}</math>:<br>
: <math>
: <math>
Строка 65: Строка 69:
   C_{21} & C_{22}
   C_{21} & C_{22}
\end{bmatrix}.
\end{bmatrix}.
Для вычисления матриц <math> \alpha_{i}, i = \overline{1,7} </math> также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка <math> \frac{n}{2} </math>. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера <math>k</math> к задаче размера <math>\frac{k}{2}</math>. Рекурсивный процесс продолжается до тех пор, пока <math>k</math> не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.
Для вычисления матриц <math> \alpha_{i}, i = \overline{1,7} </math> также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка <math> \frac{n}{2} </math>. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера <math>k</math> к задаче размера <math>\frac{k}{2}</math>. Рекурсивный процесс продолжается до тех пор, пока <math>k</math> не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.



Версия от 20:18, 16 октября 2017

Основные авторы описания: Ю.В.Рябкова

Свойства и структура алгоритмов

Общее описание алгоритма

Алгоритм Штрассена, описанный в 1969 году Фолькером Штрассеном, предназначен для умножения двух произвольных матриц при условии согласованности их размеров. В данном варианте алгоритма будет рассмотрен только частный случай умножения квадратных матриц порядка [math]\displaystyle{ n }[/math] над полем вещественных чисел [math]\displaystyle{ \mathbb{R} }[/math].

В 1965 году Штрассен нашел способ умножения двух матриц размера [math]\displaystyle{ 2 \times 2 }[/math] с использованием семи умножений, в то время как классический алгоритм перемножения матриц требует восьми умножений. Стоит отметить, что данный способ не использует свойство коммутативности для операции перемножения чисел.

Теперь предположим, что [math]\displaystyle{ n = 2^L }[/math], [math]\displaystyle{ L \in \mathbb{N} }[/math] (далее будет показано, что это предположение не нарушает общности рассуждений), и будем рассматривать матрицы [math]\displaystyle{ A }[/math] и [math]\displaystyle{ B }[/math] как блочные [math]\displaystyle{ 2 \times 2 }[/math]-матрицы с размером блоков [math]\displaystyle{ \frac{n}{2} \times \frac{n}{2} }[/math]. Так как для блочных матриц правила умножения остаются теми же, как если бы на месте блока стояло число, а в методе Штрассена умножения [math]\displaystyle{ 2 \times 2 }[/math]-матриц не используется коммутативность, этот метод подходит и для умножения блочных [math]\displaystyle{ 2 \times 2 }[/math]-матриц. Таким образом, от задачи умножения [math]\displaystyle{ 2 \times 2 }[/math]-матриц с семью умножениями можно перейти к задаче умножения [math]\displaystyle{ n \times n }[/math]-матриц, требующей не более чем [math]\displaystyle{ O(7n^{\log_27}) }[/math] операций, что асимптотически лучше классического способа умножения матриц сложностью [math]\displaystyle{ O(n^3) }[/math]. На данный момент известны и более быстрые методы умножения матриц, однако алгоритм Штрассена относительно прост в реализации и эффективен на плотных матрицах не очень больших размеров, поэтому всё ещё широко используется.

Математическое описание алгоритма

Пусть [math]\displaystyle{ A, B \in \mathbb{R}^{n \times n} }[/math] — заданные плотные матрицы. Вычислим матрицу [math]\displaystyle{ C \in \mathbb{R}^{n \times n} }[/math], такую, что [math]\displaystyle{ C = AB }[/math].

Для удобства будем полагать, что [math]\displaystyle{ n = 2^L, L \in \mathbb{N} }[/math]. Это предположение не ограничивает общности рассуждений, так как если это свойство не выполнено и [math]\displaystyle{ n \lt 2^L }[/math], можно рассмотреть квадратные матрицы [math]\displaystyle{ \tilde{A} }[/math] и [math]\displaystyle{ \tilde{B} }[/math] порядка [math]\displaystyle{ 2^L }[/math] следующего вида:

[math]\displaystyle{ \tilde{A} = \begin{bmatrix} A & 0 \\ 0 & 0 \end{bmatrix}, \: \: \tilde{B} = \begin{bmatrix} B & 0 \\ 0 & 0 \end{bmatrix}, }[/math]

то есть матрицы, полученные из матриц [math]\displaystyle{ A }[/math] и [math]\displaystyle{ B }[/math] дополнением их нулевыми строками и столбцами в позициях [math]\displaystyle{ i = \overline{n+1, 2^L} }[/math] до размера [math]\displaystyle{ 2^L \times 2^L }[/math]. По правилу перемножения блочных матриц:

[math]\displaystyle{ \tilde{C} = \tilde{A}\tilde{B} = \begin{bmatrix} AB & 0 \\ 0 & 0 \end{bmatrix} = \begin{bmatrix} C & 0 \\ 0 & 0 \end{bmatrix}. }[/math]

Таким образом, решая задачу для матриц [math]\displaystyle{ \tilde{A} }[/math] и [math]\displaystyle{ \tilde{B} }[/math], получим решение исходной задачи умножения матриц [math]\displaystyle{ A }[/math] и [math]\displaystyle{ B }[/math] как левый верхний [math]\displaystyle{ n \times n }[/math]-блок матрицы [math]\displaystyle{ \tilde{C} }[/math].

Итак, пусть [math]\displaystyle{ n = 2^L, L \in \mathbb{N} }[/math]. Рассмотрим матрицы A </math> и [math]\displaystyle{ B }[/math] как блочные [math]\displaystyle{ 2 \times 2 }[/math]-матрицы с квадратными блоками порядка [math]\displaystyle{ frac{n}{2} }[/math]:

[math]\displaystyle{ A = \begin{bmatrix} A_{11} & A_{12} \\ A_{21} & A_{22} \end{bmatrix}, \: \: B = \begin{bmatrix} B_{11} & B_{12} \\ B_{21} & B_{22} \end{bmatrix}. }[/math]

Их произведение [math]\displaystyle{ C = AB = }[/math], согласно алгоритму Штрассена, вычисляется следующим образом:

[math]\displaystyle{ \alpha_{1} = (A_{11} + A_{22})(B_{11} + B_{22}), }[/math]
[math]\displaystyle{ \alpha_{2} = (A_{21} + A_{22})B_{11}, }[/math]
[math]\displaystyle{ \alpha_{3} = A_{11}(B_{12} − B_{22}), }[/math]
[math]\displaystyle{ \alpha_{4} = A_{22}(B_{21} − B_{11}), }[/math]
[math]\displaystyle{ \alpha_{5} = (A_{11} + A_{12})B_{22}, }[/math]
[math]\displaystyle{ \alpha_{6} = (A_{21} − A_{11})(B_{11} + B_{12}), }[/math]
[math]\displaystyle{ \alpha_{7} = (A_{12} − A_{22})(B_{21} + B_{22}), }[/math]
[math]\displaystyle{ C_{11} = \alpha_{1} + \alpha_{4} - \alpha_{5} + \alpha_{7}, }[/math]
[math]\displaystyle{ C_{12} = \alpha_{3} + \alpha_{5}, }[/math]
[math]\displaystyle{ C_{21} = \alpha_{2} + \alpha_{4}, }[/math]
[math]\displaystyle{ C_{22} = \alpha_{1} + \alpha_{3} - \alpha_{2} + \alpha_{6}, }[/math]
[math]\displaystyle{ C = \begin{bmatrix} C_{11} & C_{12} \\ C_{21} & C_{22} \end{bmatrix}. Для вычисления матриц \lt math\gt \alpha_{i}, i = \overline{1,7} }[/math] также требуется выполнить семь матричных умножений по формулам, данным выше, но уже для матриц порядка [math]\displaystyle{ \frac{n}{2} }[/math]. Таким образом, получаем рекурсивный алгоритм, на каждом шаге рекурсии требующий семи умножений и сводящий задачу размера [math]\displaystyle{ k }[/math] к задаче размера [math]\displaystyle{ \frac{k}{2} }[/math]. Рекурсивный процесс продолжается до тех пор, пока [math]\displaystyle{ k }[/math] не станет достаточно малым, далее используется классический способ умножения матриц. Это связано с тем, что на малых матрицах алгоритм Штрассена теряет эффективность в сравнении с классическим алгоритмом, так как требует большого числа сложений.

Вычислительное ядро алгоритма

Макроструктура алгоритма

Схема реализации последовательного алгоритма

Последовательная сложность алгоритма

Информационный граф

Ресурс параллелизма алгоритма

Входные и выходные данные алгоритма

Свойства алгоритма

Программная реализация алгоритма

Особенности реализации последовательного алгоритма

Локальность данных и вычислений

Возможные способы и особенности параллельной реализации алгоритма

Масштабируемость алгоритма и его реализации

Динамические характеристики и эффективность реализации алгоритма

Выводы для классов архитектур

Существующие реализации алгоритма

Литература