我一直在尝试实现Schönhage–Strassen整数乘法算法,但是在递归步骤中遇到了绊脚石。
我有一个位的值,我想计算。我最初以为是选择一个k,使4 ^ k \ geq 2n,将x分成2 ^ k个,每个具有2 ^ {k-1}位,在对2 ^ {2 ^ k}进行模运算时应用SSA的卷积+1,即每个值具有2 ^ k位容量的环,然后将碎片放回原处。但是,卷积的输出略大于2n位(即> 2 ^ k每个输出值的位数大于环的容量,这是因为每个输出值是多个乘积之和),所以这是行不通的。我必须添加2的额外因素。
填充中的额外2因子破坏了复杂性。这使我的递归步骤太昂贵了。代替了算法用算法。
我阅读了一些来自维基百科的链接,但它们似乎都掩盖了如何解决此问题的细节。例如,我可以通过工作模避免额外的填充开销的,这不是2的幂......但后来的事情后来才破的时候我只有非功率剩下2个因素,并且在不加倍数量的情况下不能应用Cooley-Tukey。而且,可能不具有模的乘法逆。因此,仍然存在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);
...