stringtranslate.com

алгоритм Штрассена

В линейной алгебре алгоритм Штрассена , названный в честь Фолькера Штрассена , — это алгоритм умножения матриц . Он быстрее стандартного алгоритма умножения матриц для больших матриц, с лучшей асимптотической сложностью , хотя наивный алгоритм часто лучше для меньших матриц. Алгоритм Штрассена медленнее самых быстрых известных алгоритмов для чрезвычайно больших матриц, но такие галактические алгоритмы бесполезны на практике, так как они намного медленнее для матриц практичного размера. Для маленьких матриц существуют даже более быстрые алгоритмы.

Алгоритм Штрассена работает для любого кольца , например, плюс/умножение, но не для всех полуколец , например, мин-плюс или булева алгебра , где наивный алгоритм все еще работает, и для так называемого комбинаторного умножения матриц.

История

Фолькер Штрассен впервые опубликовал этот алгоритм в 1969 году и тем самым доказал, что общий алгоритм умножения матриц не является оптимальным. [1] Публикация алгоритма Штрассена привела к большему количеству исследований умножения матриц, что привело как к асимптотическим нижним границам, так и к улучшенным вычислительным верхним границам.

Алгоритм

Левый столбец визуализирует вычисления, необходимые для определения результата умножения матриц 2x2 . Наивное умножение матриц требует одного умножения для каждой «1» левого столбца. Каждый из других столбцов (M1-M7) представляет одно из 7 умножений в алгоритме Штрассена. Сумма столбцов M1-M7 дает тот же результат, что и полное умножение матриц слева.

Пусть , будут двумя квадратными матрицами над кольцом , например, матрицы, элементы которых являются целыми числами или действительными числами. Целью умножения матриц является вычисление матричного произведения . Следующее изложение алгоритма предполагает, что все эти матрицы имеют размеры, являющиеся степенями двойки (т. е. ), но это необходимо только концептуально — если матрицы , не имеют типа , «отсутствующие» строки и столбцы можно заполнить нулями, чтобы получить матрицы с размерами степеней двойки — хотя реальные реализации алгоритма на практике этого не делают.

Алгоритм Штрассена разбивает и на блочные матрицы одинакового размера

с . Наивный алгоритм будет таким:

Эта конструкция не уменьшает количество умножений: для вычисления матриц по-прежнему необходимо 8 умножений матричных блоков, столько же умножений требуется при использовании стандартного умножения матриц.

Алгоритм Штрассена вместо этого определяет новые значения:

используя только 7 умножений (по одному для каждого ) вместо 8. Теперь мы можем выразить через :

Мы рекурсивно повторяем этот процесс деления до тех пор, пока подматрицы не выродятся в числа (элементы кольца ). Если, как упоминалось выше, исходная матрица имела размер, который не был степенью 2, то полученное произведение будет иметь нулевые строки и столбцы, как и , и они затем будут удалены в этой точке, чтобы получить (меньшую) матрицу, которую мы действительно хотели.

Практические реализации алгоритма Штрассена переключаются на стандартные методы умножения матриц для достаточно малых подматриц, для которых эти алгоритмы более эффективны. Конкретная точка пересечения, для которой алгоритм Штрассена более эффективен, зависит от конкретной реализации и оборудования. Более ранние авторы подсчитали, что алгоритм Штрассена быстрее для матриц шириной от 32 до 128 для оптимизированных реализаций. [2] Однако было замечено, что эта точка пересечения увеличивается в последние годы, и исследование 2010 года показало, что даже один шаг алгоритма Штрассена часто не приносит пользы на текущих архитектурах по сравнению с высокооптимизированным традиционным умножением, пока размеры матриц не превысят 1000 или более, и даже для размеров матриц в несколько тысяч преимущество обычно в лучшем случае незначительно (около 10% или меньше). [3] Более недавнее исследование (2016 г.) наблюдало преимущества для матриц размером от 512 и преимущество около 20%. [4]

форма Винограда

Можно сократить количество матричных сложений, используя вместо этого следующую форму, открытую Виноградом:

где .

Это сокращает количество сложений и вычитаний матриц с 18 до 15. Количество умножений матриц по-прежнему равно 7, а асимптотическая сложность та же. [5]

Асимптотическая сложность

Схема алгоритма выше показала, что можно обойтись всего 7, вместо традиционных 8, умножений матриц на матрицу для подблоков матрицы. С другой стороны, нужно делать сложения и вычитания блоков, хотя это не имеет значения для общей сложности: сложение матриц размера требует только операций, тогда как умножение существенно дороже (традиционно операции сложения или умножения).

Тогда возникает вопрос, сколько именно операций требуется для алгоритмов Штрассена и как это соотносится со стандартным умножением матриц, которое требует приблизительно (где ) арифметических операций, т.е. имеет асимптотическую сложность .

Число сложений и умножений, требуемых в алгоритме Штрассена, можно вычислить следующим образом: пусть будет числом операций для матрицы. Затем, рекурсивно применяя алгоритм Штрассена, мы видим, что , для некоторой константы , которая зависит от числа сложений, выполняемых при каждом применении алгоритма. Следовательно , , т. е. асимптотическая сложность умножения матриц размера с использованием алгоритма Штрассена равна . Однако уменьшение числа арифметических операций достигается ценой несколько сниженной численной устойчивости , [6] и алгоритм также требует значительно больше памяти по сравнению с наивным алгоритмом. Обе исходные матрицы должны иметь расширенные размеры до следующей степени 2, что приводит к хранению в четыре раза большего количества элементов, а семь вспомогательных матриц содержат каждая четверть элементов в расширенных.

Алгоритм Штрассена необходимо сравнить с «наивным» способом выполнения умножения матриц, который потребовал бы 8 вместо 7 умножений подблоков. Это затем привело бы к сложности, которую можно ожидать от стандартного подхода: . Сравнение этих двух алгоритмов показывает, что асимптотически алгоритм Штрассена быстрее: существует размер , так что матрицы большего размера более эффективно умножаются алгоритмом Штрассена, чем «традиционным» способом. Однако асимптотическое утверждение не подразумевает, что алгоритм Штрассена всегда быстрее даже для небольших матриц, и на практике это фактически не так: для небольших матриц стоимость дополнительных добавлений блоков матриц перевешивает экономию в количестве умножений. Есть также другие факторы, не охваченные вышеприведенным анализом, такие как разница в стоимости сегодняшнего оборудования между загрузкой данных из памяти на процессоры и стоимостью фактического выполнения операций с этими данными. Вследствие таких соображений алгоритм Штрассена обычно используется только на «больших» матрицах. Этот эффект еще более выражен в альтернативных алгоритмах, таких как алгоритм Копперсмита и Винограда : хотя асимптотически он даже быстрее, точка кроссинговера настолько велика, что алгоритм обычно не используется на матрицах, с которыми приходится сталкиваться на практике.

Ранговая или билинейная сложность

Билинейная сложность или ранг билинейного отображения является важным понятием в асимптотической сложности умножения матриц. Ранг билинейного отображения над полем F определяется как (несколько злоупотребление обозначениями )

Другими словами, ранг билинейного отображения — это длина его кратчайшего билинейного вычисления. [7] Существование алгоритма Штрассена показывает, что ранг умножения матриц не больше семи. Чтобы увидеть это, выразим этот алгоритм (наряду со стандартным алгоритмом) как такое билинейное вычисление. В случае матриц двойственные пространства A * и B * состоят из отображений в поле F , индуцированных скалярным произведением с двумя точками (т.е. в этом случае суммой всех элементов произведения Адамара .)

Можно показать, что общее число элементарных умножений, требуемых для умножения матриц, асимптотически тесно связано с рангом , т. е . , или, более конкретно, поскольку константы известны, . Одним из полезных свойств ранга является то, что он является субмультипликативным для тензорных произведений , и это позволяет показать, что умножение матриц может быть выполнено не более чем за элементарные умножения для любого . (Это -кратное тензорное произведение отображения умножения матриц на себя — -я степень тензора — реализуется рекурсивным шагом в показанном алгоритме.)

Поведение кэша

Алгоритм Штрассена не обращает внимания на кэш . Анализ его алгоритма поведения кэша показал, что он подвергается

промахи кэша во время его выполнения, предполагая идеализированный кэш размером (т.е. со строками длиной ). [8] : 13 

Соображения по реализации

В описании выше указано, что матрицы являются квадратными, а их размер равен степени двойки, и что при необходимости следует использовать заполнение. Это ограничение позволяет рекурсивно делить матрицы пополам до тех пор, пока не будет достигнут предел скалярного умножения. Ограничение упрощает объяснение и анализ сложности, но на самом деле не является необходимым; [9] и на самом деле заполнение матрицы, как описано, увеличит время вычислений и может легко устранить довольно узкую экономию времени, полученную при использовании метода в первую очередь.

Хорошая реализация будет соответствовать следующим требованиям:

Более того, нет необходимости, чтобы матрицы были квадратными. Неквадратные матрицы можно разделить пополам, используя те же методы, что даст меньшие неквадратные матрицы. Если матрицы достаточно неквадратные, то будет целесообразно сократить начальную операцию до более квадратных произведений, используя простые методы, которые по сути являются , например:

Эти методы усложнят реализацию по сравнению с простым дополнением до квадрата степени двойки; однако разумно предположить, что любой, кто возьмется за реализацию метода Штрассена, а не обычного умножения, будет отдавать больший приоритет вычислительной эффективности, чем простоте реализации.

На практике алгоритм Штрассена может быть реализован для достижения лучшей производительности, чем обычное умножение, даже для матриц размером до , для матриц, которые совсем не являются квадратными, и без необходимости использования рабочего пространства за пределами буферов, которые уже необходимы для высокопроизводительного обычного умножения. [4]

Смотрите также

Ссылки

  1. ^ Штрассен, Фолькер (1969). «Gaussian Elimination is not Optimal». Numer. Math . 13 (4): 354–356. doi :10.1007/BF02165411. S2CID  121656251.
  2. ^ Скиена, Стивен С. (1998), "§8.2.3 Матричное умножение", Руководство по разработке алгоритмов , Берлин, Нью-Йорк: Springer-Verlag , ISBN 978-0-387-94860-7.
  3. ^ ab D'Alberto, Paolo; Nicolau, Alexandru (2005). Использование рекурсии для повышения производительности ATLAS (PDF) . Шестой международный симпозиум по высокопроизводительным вычислениям.
  4. ^ ab Huang, Jianyu; Smith, Tyler M.; Henry, Greg M.; van de Geijn, Robert A. (13 ноября 2016 г.). Перезагрузка алгоритма Штрассена. SC16: Международная конференция по высокопроизводительным вычислениям, сетевым технологиям, хранению и анализу. IEEE Press. стр. 690–701. doi :10.1109/SC.2016.58. ISBN 9781467388153. Получено 1 ноября 2022 г. .
  5. ^ Кнут (1997), стр. 500.
  6. ^ Вебб, Миллер (1975). «Вычислительная сложность и численная устойчивость». SIAM J. Comput . 4 (2): 97–107. doi :10.1137/0204009.
  7. ^ Бургиссер; Клаузен; Шокроллахи (1997). Алгебраическая теория сложности . Спрингер-Верлаг. ISBN 3-540-60582-7.
  8. ^ Фриго, М.; Лейзерсон, К. Э.; Прокоп , Х.; Рамачандран, С. (1999). Алгоритмы, забывающие о кэше (PDF) . Труды симпозиума IEEE по основам компьютерной науки (FOCS). стр. 285–297.
  9. ^ Хайэм, Николас Дж. (1990). «Использование быстрого умножения матриц в BLAS уровня 3» (PDF) . ACM Transactions on Mathematical Software . 16 (4): 352–368. doi :10.1145/98267.98290. hdl : 1813/6900 . S2CID  5715053.

Внешние ссылки