Toom–Cook , иногда известный как Toom-3 , названный в честь Андрея Тоома , представившего новый алгоритм с его низкой сложностью, и Стивена Кука , подчистившего его описание, представляет собой алгоритм умножения больших целых чисел.
Учитывая два больших целых числа, a и b , Тум-Кук разбивает a и b на k меньших частей, каждая длиной l , и выполняет операции над частями. По мере роста k можно объединить многие подоперации умножения, тем самым уменьшая общую вычислительную сложность алгоритма. Подоперации умножения затем можно вычислить рекурсивно, снова используя умножение Тума – Кука, и так далее. Хотя термины «Тум-3» и «Тум-Кук» иногда неправильно используются как взаимозаменяемые, Тоом-3 представляет собой лишь один экземпляр алгоритма Тум-Кука, где k = 3.
Toom-3 сокращает девять умножений до пяти и работает за Θ( n log(5)/log(3) ) ≈ Θ( n 1,46 ). В общем, Toom- k работает в Θ( c ( k ) n e ) , где e = log(2 k − 1) / log( k ) , n e — время, затраченное на частичное умножение, а c — время тратится на сложение и умножение на небольшие константы. [1] Алгоритм Карацубы эквивалентен Тоом-2, где число разбивается на два меньших. Он сокращает четыре умножения до трех и поэтому работает при Θ( n log(3)/log(2) ) ≈ Θ( n 1,58 ).
Хотя показатель степени e можно установить сколь угодно близким к 1, увеличивая k , постоянный член функции растет очень быстро. [1] [2] Скорость роста для схем Тума – Кука смешанного уровня все еще оставалась открытой исследовательской проблемой в 2005 году. [3] Реализация, описанная Дональдом Кнутом, достигает временной сложности Θ( n 2 √ 2 log n log n ) . [4]
Из-за накладных расходов алгоритм Тума-Кука медленнее, чем длинное умножение с небольшими числами, и поэтому он обычно используется для умножений промежуточного размера перед асимптотически более быстрым алгоритмом Шенхаге-Штрассена (со сложностью Θ( n log n log log n ) ). становится практичным.
Тум впервые описал этот алгоритм в 1963 году, а Кук опубликовал улучшенный (асимптотически эквивалентный) алгоритм в своей докторской диссертации в 1966 году. [5]
В этом разделе обсуждается, как именно выполнить Toom- k для любого заданного значения k , и он представляет собой упрощенное описание умножения полиномов Тума – Кука, описанное Марко Бодрато. [6] Алгоритм состоит из пяти основных шагов:
В типичной реализации большого целого числа каждое целое число представляется как последовательность цифр в позиционной записи с основанием или основанием системы счисления, установленным на некоторое (обычно большое) значение b ; в этом примере мы используем b = 10000, так что каждая цифра соответствует группе из четырех десятичных цифр (в компьютерной реализации вместо этого b обычно будет степенью 2). Предположим, что умножаются два целых числа:
Они намного меньше, чем обычно обрабатываются с помощью Тума-Кука (умножение в начальной школе будет быстрее), но они послужат для иллюстрации алгоритма.
В Toom- k мы хотим разделить факторы на k частей.
Первый шаг — выбрать базу B = b i так, чтобы количество цифр m и n в базе B было не более k (например, 3 в Toom-3). Типичный выбор для i определяется следующим образом:
В нашем примере мы будем использовать Toom-3, поэтому выбираем B = b 2 = 10 8 . Затем мы разделяем m и n на их базовые B- цифры m i , n i :
Затем мы используем эти цифры в качестве коэффициентов в полиномах p и q степени ( k − 1) со свойством, что p ( B ) = m и q ( B ) = n :
Целью определения этих многочленов является то, что если мы сможем вычислить их произведение r ( x ) = p ( x ) q ( x ) , наш ответ будет r ( B ) = m × n .
В случае , когда умножаемые числа имеют разные размеры, полезно использовать разные значения k для m и n , которые мы будем называть km и k n . Например, алгоритм «Toom-2.5» относится к Туму-Куку с k m = 3 и k n = 2. В этом случае i в B = b i обычно выбирается по формуле:
Подход Тума – Кука для вычисления полиномиального произведения p ( x ) q ( x ) является широко используемым. Заметим, что многочлен степени d однозначно определяется d + 1 точкой (например, линия-полином первой степени задается двумя точками). Идея состоит в том, чтобы оценить p (·) и q (·) в различных точках. Затем умножьте их значения в этих точках, чтобы получить баллы на полиноме произведения. Наконец, интерполируйте, чтобы найти его коэффициенты.
Поскольку deg( pq ) = deg( p ) + deg( q ) , нам понадобится deg( p ) + deg( q ) + 1 = k m + k n − 1 очков для определения окончательного результата. Назовите это д . В случае Тоом-3 d = 5. Алгоритм будет работать независимо от того, какие точки выбраны (за некоторыми небольшими исключениями, см. требование обратимости матрицы в разделе «Интерполяция»), но в интересах упрощения алгоритма лучше выбирать небольшие целочисленные значения, такие как 0, 1, -1 и -2.
Одно необычное значение точки, которое часто используется, — это бесконечность, обозначаемая ∞ или 1/0. «Оценить» полином p на бесконечности на самом деле означает взять предел p ( x )/ x deg p , когда x стремится к бесконечности. Следовательно, p (∞) всегда является значением своего коэффициента старшей степени (в приведенном выше примере коэффициента m 2 ).
В нашем примере Toom-3 мы будем использовать точки 0, 1, −1, −2 и ∞. Этот выбор упрощает оценку, создавая формулы:
и аналогично для q . В нашем примере мы получаем следующие значения:
Как показано, эти значения могут быть отрицательными.
В целях дальнейшего объяснения будет полезно рассматривать этот процесс оценки как умножение матрицы на вектор, где каждая строка матрицы содержит степени одной из точек оценки, а вектор содержит коэффициенты полинома:
Размеры матрицы равны d на km для p и d на k n для q . Строка для бесконечности всегда равна нулю, за исключением 1 в последнем столбце.
Многоточечную оценку можно получить быстрее, чем с помощью приведенных выше формул. Количество элементарных операций (сложение/вычитание) можно сократить. Последовательность, заданная Бодрато [6] для Toom-3, выполняемая здесь над первым операндом (многочленом p ) текущего примера, следующая:
Эта последовательность требует пяти операций сложения/вычитания, что на одну меньше, чем при прямом вычислении. При этом умножение на 4 при вычислении p (−2) было сохранено.
В отличие от умножения полиномов p (·) и q (·), умножение вычисленных значений p ( a ) и q ( a ) включает в себя просто умножение целых чисел — меньший экземпляр исходной проблемы. Мы рекурсивно вызываем нашу процедуру умножения для умножения каждой пары оцененных точек. В практических реализациях, когда операнды становятся меньше, алгоритм переключается на умножение в длину, как в школьном учебнике . Полагая r полиномом произведения, в нашем примере мы имеем:
Как показано, они также могут быть отрицательными. Для достаточно больших чисел это самый затратный шаг, единственный шаг, который не является линейным по размерам m и n .
Это самый сложный шаг, обратный шагу оценки: учитывая наши d точек на полиноме произведения r (·), нам нужно определить его коэффициенты. Другими словами, мы хотим решить это матричное уравнение для вектора в правой части:
Эта матрица строится так же, как и на этапе оценки, за исключением того, что она имеет размер d × d . Мы могли бы решить это уравнение с помощью метода исключения Гаусса , но это слишком дорого. Вместо этого мы используем тот факт, что при правильном выборе точек оценки эта матрица обратима (см. также матрицу Вандермонда ), и поэтому:
Остается только вычислить это произведение матрицы на вектор. Хотя матрица содержит дроби, результирующие коэффициенты будут целыми числами — так что все это можно сделать с помощью целочисленной арифметики, просто сложения, вычитания и умножения / деления на небольшие константы. Сложная задача проектирования в Туме – Куке состоит в том, чтобы найти эффективную последовательность операций для вычисления этого продукта; одна последовательность, данная Бодрато [6] для Тоом-3, следующая: она выполняется здесь на примере текущего примера:
Теперь мы знаем наш полином произведения r :
Если бы мы использовали разные km , k n или точки оценки, матрица и, следовательно, наша стратегия интерполяции изменились бы ; но это не зависит от входных данных и поэтому может быть жестко запрограммировано для любого заданного набора параметров.
Наконец, мы оцениваем r(B), чтобы получить окончательный ответ. Это просто, поскольку B является степенью b , и поэтому все умножения на степени B представляют собой сдвиги на целое число цифр по базе b . В текущем примере b = 10 4 и B = b 2 = 10 8 .
А это на самом деле произведение 1234567890123456789012 и 987654321987654321098.
Здесь мы приводим общие матрицы интерполяции для нескольких различных общих малых значений km и k n .
Применяя формально определение, мы можем рассмотреть Toom-1 ( k m = k n = 1). Это дает не алгоритм умножения, а рекурсивный алгоритм, который никогда не останавливается, поскольку он тривиально сводит каждый входной экземпляр к рекурсивному вызову одного и того же экземпляра. Алгоритму требуется 1 точка оценки, значение которой не имеет значения, поскольку оно используется только для «оценки» постоянных полиномов. Таким образом, матрица интерполяции является единичной матрицей:
Toom-1.5 ( k m = 2, k n = 1) все еще является вырожденным: он рекурсивно уменьшает один вход, уменьшая его размер вдвое, но оставляет другой вход неизменным, следовательно, мы можем превратить его в алгоритм умножения, только если мы предоставим 1 Алгоритм умножения × n как базовый вариант (тогда как истинный алгоритм Тума – Кука сводится к базовым случаям постоянного размера). Для этого требуется 2 оценочных балла, здесь выбраны значения 0 и ∞. Его интерполяционная матрица тогда является единичной матрицей:
Алгоритм по существу эквивалентен форме длинного умножения: оба коэффициента одного фактора умножаются на единственный коэффициент другого фактора.
Toom-2 ( k m = 2, k n = 2) требует 3 оценочных балла, здесь выбраны значения 0, 1 и ∞. Это то же самое, что и умножение Карацубы , с матрицей интерполяции:
Toom-2.5 ( k m = 3, k n = 2) требует 4 оценочных балла, здесь выбраны значения 0, 1, −1 и ∞. Затем он имеет матрицу интерполяции: