这个显然是O(n lg n)乘法算法的错误在哪里?


15

最近一篇有关找到三个等距间隔的难题的博客文章将我引向一个stackoverflow问题,该问题的最高答案声称是在O(n lg n)时间内完成的。有趣的是,该解决方案涉及对多项式求平方,并参考描述了如何在O(n lg n)时间内进行的论文

现在,多项式相乘实际上与数字相乘。唯一真正的区别是缺少携带。但是...进位也可以在O(n lg n)时间内完成。例如:

    var value = 100; // = 0b1100100

    var inputBitCount = value.BitCount(); // 7 (because 2^7 > 100 >= 2^6)
    var n = inputBitCount * 2; // 14
    var lgn = n.BitCount(); // 4 (because 2^4 > 14 => 2^3)
    var c = lgn + 1; //5; enough space for 2n carries without overflowing

    // do apparently O(n log n) polynomial multiplication
    var p = ToPolynomialWhereBitsAreCoefficients(value); // x^6 + x^5 + x^2
    var p2 = SquarePolynomialInNLogNUsingFFT(p); // x^12 + 2x^11 + 2x^10 + x^8 + 2x^7 + x^4
    var s = CoefficientsOfPolynomial(p2); // [0,0,0,0,1,0,0,2,1,0,2,2,1]
    // note: s takes O(n lg n) space to store (each value requires at most c-1 bits)

    // propagate carries in O(n c) = O(n lg n) time
    for (var i = 0; i < n; i++)
        for (var j = 1; j < c; j++)
            if (s[i].Bit(j))
                s[i + j].IncrementInPlace();

    // extract bits of result (in little endian order)
    var r = new bool[n];
    for (var i = 0; i < n; i++)
        r[i] = s[i].Bit(0);

    // r encodes 0b10011100010000 = 10000

所以我的问题是:错误在哪里?O(n lg n)中的数字相乘是计算机科学中的一个巨大的开放问题,我真的很怀疑答案是否会如此简单。

  • 是携带错误,还是O(n lg n)?我已经计算出,每个值lg n + 1位足以跟踪进位,并且算法是如此简单,如果发现错误,我会感到惊讶。注意,尽管单个增量可能花费O(lg n)时间,但x增量的总成本为O(x)。
  • 本文中的多项式乘法算法是错误的,还是存在我违反的条件?本文使用快速傅立叶变换代替了数论变换,这可能是一个问题。
  • 有很多聪明人错过了Schönhage–Strassen算法 40年的明显变体吗?到目前为止,这似乎是最不可能的。

我实际上已经编写了实现此目的的代码,除了有效的多项式乘法(我对数字理论变换还不够了解)。随机测试似乎可以确认算法正确,因此在时间复杂度分析中很可能会出现此问题。


广场不应该包括x^10 + 2x^8吗?x ^ 10仅一次(x ^ 5 * x ^ 5),x ^ 8两次(x ^ 6 * x ^ 2 + x ^ 2 * x ^ 6)
Sjoerd 2013年

我是手工做的例子。我犯了一个数学错误。抱歉。我实际上确实实现了该算法并对其进行了测试,并获得了正确的结果。
Craig Gidney

Answers:



1

这里的“错误”是可以在O(n log n)个步骤中对要转换的数字进行加或乘运算来进行傅立叶变换,但是随着n的变大,要转换的数字也将变大,从而增加另一个因素日志。

在实践中,我认为在FFT中使用四精度浮点(使用两个双精度值的128位浮点)或128位固定点就足够了,因为任何乘积都足够小,可以完全计算出来。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.