numpy有效地计算多项式 [英] numpy calculate polynom efficiently

查看:213
本文介绍了numpy有效地计算多项式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用numpy评估多项式(3度). 我发现通过更简单的python代码执行此操作会更加高效.

I'm trying to evaluate polynomial (3'd degree) using numpy. I found that doing it by simpler python code will be much more efficient.

import numpy as np
import timeit

m = [3,7,1,2]

f = lambda m,x: m[0]*x**3 + m[1]*x**2 + m[2]*x + m[3]
np_poly = np.poly1d(m)
np_polyval = lambda m,x: np.polyval(m,x)
np_pow = lambda m,x: np.power(x,[3,2,1,0]).dot(m)

print 'result={}, timeit={}'.format(f(m,12),timeit.Timer('f(m,12)', 'from __main__   import f,m').timeit(10000))
result=6206, timeit=0.0036780834198

print 'result={}, timeit={}'.format(np_poly(12),timeit.Timer('np_poly(12)', 'from __main__ import np_poly').timeit(10000))
result=6206, timeit=0.180546045303

print 'result={}, timeit={}'.format(np_polyval(m,12),timeit.Timer('np_polyval(m,12)', 'from __main__ import np_polyval,m').timeit(10000))
result=6206, timeit=0.227771043777

print 'result={}, timeit={}'.format(np_pow(m,12),timeit.Timer('np_pow(m,12)', 'from __main__ import np_pow,m').timeit(10000))
result=6206, timeit=0.168987989426

我错过了什么吗?

numpy中还有另一种方法来评估多项式吗?

Is there another way in numpy to evaluate a polynomial?

推荐答案

好吧,看一下polyval的实现(当评估一个poly1d时最终会调用该函数),看来实现者决定将其包括在内很奇怪一个显式循环...来自numpy 1.6.2的源代码:

Well, looking at the implementation of polyval (which is the function eventually being called when you eval a poly1d), it seems weird the implementor decided to include an explicit loop... From the source of numpy 1.6.2:

def polyval(p, x):
    p = NX.asarray(p)
    if isinstance(x, poly1d):
        y = 0
    else:
        x = NX.asarray(x)
        y = NX.zeros_like(x)
    for i in range(len(p)):
        y = x * y + p[i]
    return y

一方面,在速度上避免电源操作是有利的,另一方面,python级别的循环几乎把事情搞砸了.

On one hand, avoiding the power operation should be advantageous speed-wise, on the other hand, the python-level loop pretty much screws things up.

这是另一种numpy式的实现:

Here's an alternative numpy-ish implemenation:

POW = np.arange(100)[::-1]
def g(m, x):
    return np.dot(m, x ** POW[m.size : ])

为了提高速度,我避免在每次调用时重新创建电源阵列.另外,为公平起见,在对numpy进行基准测试时,您应该从numpy数组而不是列表开始,以避免在每次调用时将列表转换为numpy的麻烦.

For speed, I avoid recreating the power array on each call. Also, to be fair when benchmarking against numpy, you should start with numpy arrays, not lists, to avoid the penalty of converting the list to numpy on each call.

因此,添加m = np.array(m)时,我上面的g仅比f慢50%.

So, when adding m = np.array(m), my g above only runs about 50% slower than your f.

尽管在您发布的示例中速度较慢,但​​要评估标量x上的低次多项式,您确实不能比显式实现(例如您的f)快得多(当然,您可以,但如果不依靠编写较低级别的代码,可能不会很多).但是,对于较高的度数(必须将您的显式表达式替换为某种循环),随着度数的增加,numpy方法(例如g)将证明快得多,对于矢量化求值(即当是向量.

Despite being slower on the example you posted, for evaluating a low-degree polynomial on a scalar x, you really can't do much faster than an explict implemenation (like your f) (of course you can, but probably not by much without resorting to writing lower-level code). However, for higher degrees (where you have to replace you explict expression with some sort of a loop), the numpy approach (e.g. g) would prove much faster as the degree increases, and also for vectorized evaluation, i.e. when x is a vector.

这篇关于numpy有效地计算多项式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆