python - python中最快的多项式计算

标签 python algorithm performance numpy

我正在开展一个 build 牛顿盆地的旧项目,我正在努力使其尽可能快。我要加快速度的第一件事是如何在给定的复点 x0 处计算多项式函数。我想到了 4 种不同的方法来做到这一点,并使用 timeit 对其进行了测试。我使用的代码如下:

import timeit
import numpy as np
import random
from numpy import polyval

class Test(object):
    re = random.randint(-40000, 40000)/10000
    im = random.randint(-40000, 40000)/10000
    x0 = complex(re, im)
    coefs = np.array([48,8,4,-10,2,-3,1])
    flip_coefs = np.flip(coefs)

    def solve0():
        y = np.array([Test.coefs[i]*(Test.x0**i) for i in range(len(Test.coefs))]).sum()
        return y

    def solve1():
        y = 0
        for i in range(len(Test.coefs)):
            y += Test.coefs[i]*(Test.x0**i)
        return y

    def solve2():
        y = np.dot(Test.coefs,Test.x0**np.arange(len(Test.coefs)))
        return y

    def solve3():
        y = polyval(Test.flip_coefs, Test.x0)
        return y


Test.solve0()


if __name__ == '__main__':
    print(timeit.timeit('Test.solve0()', setup="from __main__ import Test", number=10000))
    print(timeit.timeit('Test.solve1()', setup="from __main__ import Test", number=10000))
    print(timeit.timeit('Test.solve2()', setup="from __main__ import Test", number=10000))
    print(timeit.timeit('Test.solve3()', setup="from __main__ import Test", number=10000))

问题是,我非常确定 numpy.polyval() 是最快的,但似乎在 Linux 上,np.dot(coefs,x**np .arange(len(coefs))) 的速度是两倍多,无论 x0 的值如何(我不知道在 Windows 和 MacOS 中是否相同)。这是我得到的输出示例:

0.1735437790002834
0.12607222800033924
0.0313361469998199
0.0796813930001008

这看起来很奇怪,因为 numpy.polyval() 是专门为求解多项式而构建的。所以,我的问题是:这里是否缺少一些东西(可能与我选择的系数有关)?有没有更快的方法来计算多项式?

最佳答案

检查 source code观察 numpy 的 polyval() 函数,您会发现这是一个纯粹的 Python 函数。 Numpy 使用 Horner 的方法进行多项式求值(并且有助于同时求值多个点,尽管这种情况不适用于此处)。

回答您关于评估费用的问题,我相信Horner's method从算法的角度来看是最佳的:它允许仅使用 n 次乘法和 n 加法来计算 n 次多项式,这与您的最快的方法 solve2(),其中乘法运算随输入大小按多项式缩放。就计算速度而言,我怀疑您的方法与 polyval() 函数相比性能的提高来自于这样一个事实:numpy 中的点积是用 C 实现的,并且在那个前面。

附录:对于该主题的全面概述,我强烈推荐 Knuth 的 The Art of Computer Programming. Vol. 2: Seminumerical Algorithms (3rd ed.) ,其中第485页的4.6.4节提到了这种情况。我相信霍纳的方法对于单个多项式评估来说是最佳的,但是如果要多次评估该多项式,那么如果允许预处理,则可能会获得进一步的加速。

关于python - python中最快的多项式计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64793458/

相关文章:

python - 使用 selenium 和 python 捕获 AJAX 响应

algorithm - 解析上下文无关文法

c# - 字符串列表到一个字符串

python - 如何解析key :value format?中的url参数

python - 如何在 pd.dataframe 的特定组中找到相交和唯一的字符串?

java - while循环停止条件缺失

python - 在python中查找一组字符串的最小汉明距离

c# - 低级差异 : non-static class with static method vs. 静态类与静态方法

android - 在 while 循环中读取 SharedPreferences 的坏习惯?

python - 简单的 Numpy 向量化