Saya telah mencoba untuk mengimplementasikan algoritma multiplikasi integer Schönhage-Strassen, tetapi menabrak batu sandungan pada langkah rekursif.
Saya memiliki nilai dengan bit dan saya ingin menghitung . Awalnya saya pikir idenya adalah untuk memilih sehingga , pisahkan menjadi masing-masing dengan bit, terapkan konvolusi SSA saat bekerja modulo , sebuah cincin dengan bit kapasitas per nilai, lalu kumpulkan kembali. Namun, output konvolusi memiliki sedikit lebih dari bit (yaitun x 2k 4 k ≥ 2 n x 2 k 2 k - 1 2 2 k + 1 2 k 2 n > 2 kbit per nilai output, yang lebih dari kapasitas cincin, karena setiap nilai output merupakan jumlah dari beberapa produk) jadi ini tidak berfungsi. Saya harus menambahkan faktor tambahan 2 padding.
Faktor tambahan 2 di padding merusak kompleksitas. Itu membuat langkah rekursif saya terlalu mahal. Alih-alih algoritma , saya berakhir dengan algoritma.
Saya membaca beberapa referensi yang ditautkan dari wikipedia, tetapi semuanya sepertinya mengabaikan detail bagaimana masalah ini diselesaikan. Sebagai contoh, saya dapat menghindari overhead padding tambahan dengan bekerja modulo untuk yang bukan kekuatan 2 ... tapi kemudian hal-hal baru saja pecah, ketika saya hanya memiliki non-power- dari-2 faktor yang tersisa dan tidak dapat menerapkan Cooley-Tukey tanpa menggandakan jumlah bagian. Juga, mungkin tidak memiliki modul invers multiplikatif . Jadi masih ada faktor paksa dari 2 yang diperkenalkan.
Bagaimana cara memilih cincin untuk digunakan selama langkah rekursif, tanpa menghilangkan kerumitan asimptotik?
Atau, dalam bentuk kode semu:
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);
...