【问题标题】:Implementing Karatsuba algorithm in Haskell在 Haskell 中实现 Karatsuba 算法
【发布时间】:2013-06-07 17:33:05
【问题描述】:

我刚刚了解了 Karatsuba 算法,并尝试在 Haskell 中实现它。

这是我的代码:

(***) :: Integer -> Integer -> Integer
x *** y
    | max x y < ub = x*y    
    | otherwise =z2*base*base + ((x1+x0)***(y1+y0)-z2-z0)*base + z0
        where
            base =10^((length . show $ max x y) `div` 2)
            z2 =x1***y1
            z0 = x0***y0
            (x1, x0) = helper x
            (y1, y0) = helper y
            helper n = (n `div` base, n `mod` base)
            ub = 10000

只要我检查像 20 -30 位这样的大数字并且对 10-20 位数字足够快,这就能准确地工作。但是,这比正常的* 在 100 位甚至更大的数字时要慢很多。我怎样才能改进这个算法?

【问题讨论】:

  • 这个base =10^((length . show $ max x y) div`2)`不好。尽管 GHC 的 Integer 实例比 Java 的 BigInteger.toString() 或 Python 的 str 快几个数量级,但它仍然相当慢(想想它必须做什么) .您应该在那里使用GHC.Float.integerLogBase 获得很好的加速。如果您使用 2 次方基数可能会更好。

标签: algorithm haskell multiplication


【解决方案1】:

实际上,我怀疑您是否可以提高性能以击败天真的运算符 - Haskell 在后台使用GMP,当算法适用于值范围时,它应该自动使用 Toom-3 或其他算法。天真的 Karatsuba 甚至可能不会被使用,但据说 Toom 系列在算法上接近它。如果你仔细想想,GHC 没有理由不使用一些高级算法进行乘法运算,因为他们已经开箱即用地支持它。

我上次检查时,GMP 非常快,即使在正常的 double 范围内使用,也至少与 gcc 的编译结果一样快。

有一个proposal关于从 GHC 中删除 GMP,但它似乎相当不活跃。

编辑:感谢@danvari,以下是 GMP 使用的不同算法:http://gmplib.org/manual/Multiplication-Algorithms.html#Multiplication-Algorithms。当数字足够小时,似乎确实会使用 Karatsuba,并且除了通常的 Tom-Cook 系列之外,还使用了 FFT。

【讨论】:

  • 感谢您的回答。我懂了。那样的话,我的算法也不算太差,只是*真的快吗?
  • 可能是这样,至少这是我的想法。几年前我使用过 GMP,发现它很棒。看来算法很多,研究思路比较前沿,估计不会轻易被超越。
  • 我明白了。好吧,实现算法是一个很好的做法。谢谢你的回答。
  • GMP 使用以下整数乘法算法(按输入数字的大小排序):1. 朴素(教科书)算法,2. Karatsuba,3. Toom 3-Way,4. Toom 4-Way,5. 更高阶的 Toom'n'Half,6. 快速傅里叶变换乘法。
猜你喜欢
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 2013-11-19
  • 1970-01-01
相关资源
最近更新 更多