stringtranslate.com

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

Алгоритм Шёнхаге–Штрассена основан на методе быстрого преобразования Фурье (БПФ) целочисленного умножения . Этот рисунок демонстрирует умножение 1234 × 5678 = 7006652 с использованием простого метода БПФ. Основание 10 используется вместо основания 2 w для иллюстративных целей.
Шёнхаге (справа) и Штрассен (слева) играют в шахматы в Обервольфахе , 1979 г.

Алгоритм Шёнхаге–Штрассена — асимптотически быстрый алгоритм умножения больших целых чисел , опубликованный Арнольдом Шёнхаге и Фолькером Штрассеном в 1971 году. [1] Он работает путем рекурсивного применения быстрого преобразования Фурье (БПФ) к целым числам по модулю . Сложность выполнения битов для умножения двух n -значных чисел с использованием алгоритма находится в нотации O большое .

Алгоритм Шёнхаге–Штрассена был асимптотически самым быстрым методом умножения, известным с 1971 по 2007 год. Он асимптотически быстрее старых методов, таких как умножение Карацубы и Тоома–Кука , и начинает превосходить их на практике для чисел свыше 10 000–100 000 десятичных знаков. [2] В 2007 году Мартин Фюрер опубликовал алгоритм с более быстрой асимптотической сложностью. [3] В 2019 году Дэвид Харви и Йорис ван дер Хувен продемонстрировали, что многозначное умножение имеет теоретическую сложность; однако их алгоритм имеет постоянные множители, которые делают его невыносимо медленным для любой мыслимой практической задачи (см. галактический алгоритм ). [4]

Приложения алгоритма Шёнхаге–Штрассена включают большие вычисления, выполняемые ради них самих, такие как Великий интернет-поиск простых чисел Мерсенна и приближения числа π , а также практические приложения, такие как факторизация эллиптической кривой Ленстры с помощью подстановки Кронекера , которая сводит умножение полиномов к умножению целых чисел. [5] [6]

Описание

В этом разделе представлена ​​упрощенная версия алгоритма, показывающая, как вычислить произведение двух натуральных чисел по модулю числа вида , где — некоторое фиксированное число. Целые числа должны быть разделены на блоки бит, поэтому в практических реализациях важно найти правильный баланс между параметрами . В любом случае этот алгоритм предоставит способ умножения двух положительных целых чисел, при условии, что выбрано так, что .

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

Теперь выберем модуль для преобразования Фурье следующим образом. Пусть будет таким, что . Также положим , и рассмотрим элементы массивов как (произвольной точности) целые числа по модулю . Заметим, что поскольку , модуль достаточно велик, чтобы вместить любые переносы, которые могут возникнуть в результате умножения и . Таким образом, произведение (по модулю ) можно вычислить, оценив свертку . Кроме того, при , мы имеем , и поэтому является примитивным корнем th из единицы по модулю .

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

Пусть (поточечное произведение) и вычислим обратное преобразование массива , снова используя корень из единицы . Массив теперь является сверткой массивов . Наконец, произведение получается путем вычисления

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

Подробности

Каждое число в системе счисления B можно записать в виде многочлена:

Более того, умножение двух чисел можно рассматривать как произведение двух многочленов:

Потому что для : у нас есть свертка.

Используя БПФ ( быстрое преобразование Фурье ), используемое в оригинальной версии вместо НТТ ( теоретико-числовое преобразование ) [7] с правилом свертки; мы получаем

То есть; , где — соответствующий коэффициент в пространстве Фурье. Это также можно записать как: .

У нас одинаковые коэффициенты из-за линейности преобразования Фурье, а также потому, что эти полиномы состоят только из одного уникального члена на коэффициент:

и

Правило свертки:

Мы свели нашу задачу свертки к задаче произведения с помощью БПФ.

Найдя БПФ полиномиальной интерполяции каждого , можно определить искомые коэффициенты.

Этот алгоритм использует метод «разделяй и властвуй» для разделения проблемы на подзадачи.

Свертка по модуН

, где .

Сдавая в аренду:

и

где корень n-й степени , видно, что: [8]

Это значит, что можно использовать вес , а затем умножить на него.

Вместо использования веса, как на первом шаге рекурсии (когда ), можно вычислить:

В обычном БПФ, которое работает с комплексными числами, можно использовать:

Однако БПФ также может использоваться как NTT ( теоретико-числовое преобразование ) в Шёнхаге–Штрассене. Это означает, что мы должны использовать θ для генерации чисел в конечном поле (например ).

Корень из единицы в конечном поле GF( r ) — это элемент a такой, что или . Например, GF( p ) , где pпростое число , дает .

Обратите внимание, что в и в . Для этих кандидатов, в рамках его конечного поля, и поэтому действуют так, как мы хотим .

Однако те же самые алгоритмы БПФ по-прежнему можно использовать, пока θ является корнем единицы конечного поля.

Чтобы найти преобразование FFT/NTT, делаем следующее:

Первый продукт дает вклад в , для каждого k . Второй дает вклад в , из-за mod .

Чтобы сделать обратное:

или

в зависимости от того, требуется ли нормализация данных.

Для нормализации данных БПФ в определенном диапазоне выполняется умножение на , где , где m находится с помощью модульной мультипликативной обратной функции .

Подробности реализации

ПочемуН= 2М+ 1 модН

В алгоритме Шёнхаге–Штрассена . Это следует рассматривать как бинарное дерево, где есть значения в . Позволяя , для каждого K можно найти все и сгруппировать все пары в M различных групп. Использование для группировки пар посредством свертки является классической проблемой в алгоритмах. [9]

Имея это в виду, помогите нам сгруппировать в группы для каждой группы подзадач по глубине k в дереве с

Обратите внимание, что для некоторого L. Это делает N числом Ферма . При выполнении mod мы получаем кольцо Ферма.

Поскольку некоторые числа Ферма являются простыми числами Ферма, в некоторых случаях можно избежать вычислений.

Конечно, есть и другие N , которые можно было бы использовать с теми же преимуществами простого числа. Позволяя , можно получить максимальное число в двоичном числе с битами. — это число Мерсенна, которое в некоторых случаях является простым числом Мерсенна. Это естественный кандидат против числа Ферма

В поисках другогоН

Выполнение нескольких расчетов mod против различных N может быть полезным при решении целочисленного произведения. Используя китайскую теорему об остатках , после разделения M на меньшие различные типы N , можно найти ответ умножения xy [10]

Числа Ферма и числа Мерсенна — это всего лишь два типа чисел, в так называемом обобщенном числе Ферма-Мерсенна (GSM); с формулой: [11]

В этой формуле — число Ферма, а — число Мерсенна.

Эту формулу можно использовать для генерации наборов уравнений, которые можно использовать в китайской теореме об остатках (CRT): [12]

, где g — число такое, что существует x , где , предполагая, что

Кроме того; , где a — элемент, который генерирует элементы циклическим образом.

Если , где , то .

Как выбратьКдля определенногоН

Следующая формула полезна для нахождения правильного K (количества групп, на которые нужно разделить N бит) при заданном размере бит N путем вычисления эффективности: [13]

N — размер бита (используемый в ) на самом внешнем уровне. K задает группы битов, где .

n находится через N, K и k путем нахождения наименьшего x , такого, что

Если предположить, что эффективность выше 50%, а k очень мал по сравнению с остальной частью формулы, то получим

Это означает: когда что-то очень эффективно; K ограничено сверху или асимптотически ограничено сверху

Псевдокод

Следующий алогистик, стандартный модульный алгоритм умножения Шёнхаге-Штрассена (с некоторыми оптимизациями), можно найти в обзоре в [14]

  1. Разделите оба входных числа a и b на n коэффициентов по s бит каждый.

    Используйте по крайней мере ⁠ ⁠ бит для их хранения,

    разрешить кодирование значения ⁠ ⁠
  2. Взвесим оба вектора коэффициентов согласно (2.24) степенями θ , выполнив над ними циклические сдвиги.
  3. Перемешайте коэффициенты ⁠ ⁠ и ⁠ ⁠ .
  4. Оцените ⁠ ⁠ и ⁠ ⁠ . Умножение на степени ω является циклическим сдвигом.
  5. Не делайте поточечных умножений ⁠ ⁠ в ⁠ ⁠ . Если SMUL используется рекурсивно, укажите K в качестве параметра. В противном случае используйте какую-либо другую функцию умножения, например T3MUL, и затем выполните сокращение по модулю ⁠ ⁠ .
  6. Перемешайте коэффициенты произведения ⁠ ⁠ .
  7. Оцените коэффициенты произведения ⁠ ⁠ .
  8. Применяем противовесы к ⁠ ⁠ согласно (2.25). Поскольку ⁠ ⁠ следует, что ⁠ ⁠
  9. Нормализуем ⁠ ⁠ с помощью ⁠ ⁠ (снова циклический сдвиг).
  10. Сложите ⁠ ⁠ и размножьте переносы. Убедитесь, что правильно обрабатываете отрицательные коэффициенты.
  11. Выполните сокращение по модулю ⁠ ⁠ .

Дальнейшее изучение

Подробности реализации можно прочитать в книге « Prime Numbers: A Computational Perspective» . [15] Этот вариант несколько отличается от оригинального метода Шёнхаге тем, что он использует дискретное взвешенное преобразование для более эффективного выполнения негациклических сверток . Другим источником подробной информации является « The Art of Computer Programming» Кнута . [16]

Оптимизации

В этом разделе объясняется ряд важных практических оптимизаций при реализации Шёнхаге–Штрассена.

Использование другого алгоритма умножения, внутри алгоритма

Ниже определенной точки отсечения эффективнее использовать другие алгоритмы умножения, такие как умножение Тума–Кука . [17]

Трюк с квадратным корнем из 2

Идея заключается в использовании в качестве корня единицы порядка в конечном поле (это решение уравнения ), при взвешивании значений в подходе NTT (теоретико-числовое преобразование). Было показано, что это экономит 10% времени умножения целых чисел. [18]

трюк Гранлунда

Позволяя , можно вычислить и . В сочетании с CRT (китайской теоремой об остатках) для нахождения точных значений умножения uv [19]

Ссылки

  1. ^ Шёнхаге, Арнольд ; Штрассен, Волкер (1971). «Schnelle Multiplikation großer Zahlen» [Быстрое умножение больших чисел]. Вычисление (на немецком языке). 7 (3–4): 281–292. дои : 10.1007/BF02242355. S2CID  9738629.
  2. ^ Умножение Карацубы имеет асимптотическую сложность около , а умножение Тума–Кука имеет асимптотическую сложность около

    Van Meter, Rodney; Itoh, Kohei M. (2005). "Быстрое квантовое модульное возведение в степень". Physical Review . 71 (5): 052320. arXiv : quant-ph/0408006 . Bibcode : 2005PhRvA..71e2320V. doi : 10.1103/PhysRevA.71.052320. S2CID  14983569.

    Обсуждение практических точек пересечения между различными алгоритмами можно найти в: Обзор функций Magma V2.9, раздел арифметики. Архивировано 20 августа 2006 г. на Wayback Machine.

    Луис Карлос Коронадо Гарсия, «Может ли умножение Шёнхаге ускорить шифрование или дешифрование RSA? Архивировано», Технический университет, Дармштадт (2005)

    Библиотека GNU Multi-Precision использует его для значений длиной не менее 1728–7808 64-битных слов (от 33 000 до 150 000 десятичных цифр) в зависимости от архитектуры. См.:

    "Умножение БПФ (GNU MP 6.2.1)". gmplib.org . Получено 20 июля 2021 г. .

    "MUL_FFT_THRESHOLD". Уголок разработчиков GMP . Архивировано из оригинала 24 ноября 2010 г. Получено 3 ноября 2011 г.

    "MUL_FFT_THRESHOLD". gmplib.org . Получено 2021-07-20 .

  3. ^ Алгоритм Фюрера имеет асимптотическую сложность
    Фюрер, Мартин (2007). "Быстрое целочисленное умножение" (PDF) . Proc. STOC '07 . Симпозиум по теории вычислений, Сан-Диего, июнь 2007 г. стр. 57–66. Архивировано из оригинала (PDF) 2007-03-05.
    Фюрер, Мартин (2009). «Быстрое целочисленное умножение». Журнал SIAM по вычислениям . 39 (3): 979–1005. doi :10.1137/070711761. ISSN  0097-5397.

    Алгоритм Фюрера используется в библиотеке с открытым исходным кодом Basic Polynomial Algebra Subprograms (BPAS). См.: Covanov, Svyatoslav; Mohajerani, Davood; Moreno Maza, Marc; Wang, Linxiao (2019-07-08). "Big Prime Field FFT on Multi-core Processors". Труды Международного симпозиума по символьным и алгебраическим вычислениям 2019 года (PDF) . Пекин, Китай: ACM. стр. 106–113. doi :10.1145/3326229.3326273. ISBN 978-1-4503-6084-5. S2CID  195848601.

  4. ^ Харви, Дэвид; ван дер Хувен, Йорис (2021). "Целочисленное умножение за время O ( n log ⁡ n ) {\displaystyle O(n\log n)} " (PDF) . Анналы математики . Вторая серия. 193 (2): 563–617. doi :10.4007/annals.2021.193.2.4. MR  4224716. S2CID  109934776.
  5. ^ Этот метод используется в библиотеке ECM INRIA.
  6. ^ "ECMNET". members.loria.fr . Получено 2023-04-09 .
  7. ^ Беккер, Ханно; Хванг, Винсент; Дж. Канвишер, Маттиас; Панни, Лоренц (2022). «Эффективное умножение довольно малых целых чисел с использованием теоретико-числовых преобразований» (PDF) .
  8. ^ Людерс, Кристоф (2014). «Быстрое умножение больших целых чисел: реализация и анализ алгоритма DKSS». стр. 26.
  9. ^ Кляйнберг, Джон; Тардос, Ева (2005). Разработка алгоритмов (1-е изд.). Пирсон. п. 237. ИСБН 0-321-29535-8.
  10. ^ Годри, Пьеррик; Александр, Круппа; Пол, Циммерманн (2007). «Реализация алгоритма умножения больших целых чисел Шенхаге-Штрассена на основе GMP» (PDF) . п. 6.
  11. ^ С. Димитров, Васил; В. Куклев, Тодор; Д. Доневский, Борислав (1994). "Обобщенное преобразование Ферма-Мерсенна в теории чисел". стр. 2.
  12. ^ С. Димитров, Васил; В. Куклев, Тодор; Д. Доневский, Борислав (1994). "Обобщенное преобразование Ферма-Мерсенна в теории чисел". стр. 3.
  13. ^ Годри, Пьеррик; Круппа, Александр; Циммерманн, Пол (2007). «Реализация алгоритма умножения больших целых чисел Шенхаге-Штрассена на основе GMP» (PDF) . п. 2.
  14. ^ Людерс, Кристоф (2014). «Быстрое умножение больших целых чисел: реализация и анализ алгоритма DKSS». стр. 28.
  15. ^ R. Crandall & C. Pomerance. Простые числа – вычислительная перспектива . Второе издание, Springer, 2005. Раздел 9.5.6: Метод Шёнхаге, стр. 502. ISBN 0-387-94777-9 
  16. ^ Кнут, Дональд Э. (1997). "§ 4.3.3.C: Дискретные преобразования Фурье". Искусство программирования . Том 2: Получисленные алгоритмы (3-е изд.). Эддисон-Уэсли. С. 305–311. ISBN 0-201-89684-2.
  17. ^ Годри, Пьеррик; Круппа, Александр; Циммерманн, Пол (2007). «Реализация алгоритма умножения больших целых чисел Шенхаге-Штрассена на основе GMP» (PDF) . п. 7.
  18. ^ Годри, Пьеррик; Круппа, Александр; Циммерманн, Пол (2007). «Реализация алгоритма умножения больших целых чисел Шенхаге-Штрассена на основе GMP» (PDF) . п. 6.
  19. ^ Годри, Пьеррик; Круппа, Александр; Циммерманн, Пол (2007). «Реализация алгоритма умножения больших целых чисел Шенхаге-Штрассена на основе GMP» (PDF) . п. 6.