Я пытался реализовать алгоритм умножения целых чисел Шёнхаге-Штрассена, но натолкнулся на камень преткновения на рекурсивном этапе.
У меня есть значение с битами, и я хочу вычислить . Первоначально я думал, что идея состоит в том, чтобы выбрать , чтобы 4 ^ k \ geq 2n , разбить x на 2 ^ k частей, каждый с 2 ^ {k-1} битами, применить свертку SSA во время работы по модулю 2 ^ {2 ^ k} +1 , кольцо с 2 ^ k битами емкости на значение, затем соедините части вместе. Однако вывод свертки имеет чуть более 2n бит (т.е. > 2 ^ kбит на выходное значение, которое больше емкости кольца, поскольку каждое выходное значение является суммой нескольких продуктов), поэтому это не работает. Я должен был добавить дополнительный коэффициент 2 дополнения.
Этот дополнительный фактор 2 в заполнении разрушает сложность. Это делает мой рекурсивный шаг слишком дорогим. Вместо алгоритма я получаю с алгоритмом .
Я прочитал несколько ссылок, связанных с Википедией, но все они, кажется, затушевывают детали того, как эта проблема решается. Например, я мог бы избежать дополнительных накладных расходов, работая по модулю для который не является степенью 2 ... но тогда все просто сломается позже, когда у меня только не-power- из 2 факторов осталось и не может применить Кули-Тьюки без удвоения количества фигур. Кроме того, может не иметь мультипликативного обратного по модулю . Таким образом, все еще существуют вынужденные факторы 2.
Как выбрать кольцо для использования во время рекурсивного шага, не увеличивая асимптотическую сложность?
Или в форме псевдокода:
multiply_in_ring(a, b, n):
...
// vvv vvv //
// vvv HOW DOES THIS PART WORK? vvv //
// vvv vvv //
let inner_ring = convolution_ring_for_values_of_size(n);
// ^^^ ^^^ //
// ^^^ HOW DOES THIS PART WORK? ^^^ //
// ^^^ ^^^ //
let input_bits_per_piece = ceil(n / inner_ring.order);
let piecesA = a.splitIntoNPiecesOfSize(inner_ring.order, input_bits_per_piece);
let piecesB = b.splitIntoNPiecesOfSize(inner_ring.order, input_bits_per_piece);
let piecesC = inner_ring.negacyclic_convolution(piecesA, piecesB);
...