gpt4 book ai didi

python - 执行数学 sigma 和的最快、最有效和 pythonic 方法是什么?

转载 作者:太空宇宙 更新时间:2023-11-03 12:30:02 25 4
gpt4 key购买 nike

假设我想执行数学求和,比如 Madhava–Leibniz formula for π , 在 Python 中:

generated by latex.codecogs.com/gif.latex?%5Cfrac%7B%5Cpi%7D%7B4%7D%5Capprox%20%5Csum_%7Bk%3D0%7D%5E%7Bn%7D%20%5Cfrac%7B%28-1%29%5Ek%7D%7B2k+1%7D

在一个名为 Leibniz_pi() 的函数中,我可以创建一个循环来计算第 nth 个部分和,例如:

def Leibniz_pi(n):
nth_partial_sum = 0 #initialize the variable
for i in range(n+1):
nth_partial_sum += ((-1)**i)/(2*i + 1)
return nth_partial_sum

我假设使用 xrange() 之类的东西而不是 range() 会更快。使用 numpy 及其内置的 numpy.sum() 方法会更快吗?这样的例子会是什么样子?

最佳答案

我想大多数人会通过@zero 定义最快的解决方案,只使用 numpy 作为最 pythonic,但它肯定不是最快的。通过一些额外的优化,您可以将已经非常快的 numpy 实现提高 50 倍。

仅使用 Numpy (@zero)

import numpy as np
import numexpr as ne
import numba as nb

def Leibniz_point(n):
val = (-1)**n / (2*n + 1)
return val

%timeit Leibniz_point(np.arange(1000)).sum()
33.8 µs ± 203 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

利用 numexpr

n=np.arange(1000)
%timeit ne.evaluate("sum((-1)**n / (2*n + 1))")
21 µs ± 354 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

使用 Numba 编译您的函数

# with error_model="numpy", turns off division-by-zero checks 
@nb.njit(error_model="numpy",cache=True)
def Leibniz_pi(n):
nth_partial_sum = 0. #initialize the variable as float64
for i in range(n+1):
nth_partial_sum += ((-1)**i)/(2*i + 1)
return nth_partial_sum

%timeit Leibniz_pi(999)
6.48 µs ± 38.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

编辑,优化代价高昂的 (-1)**n

import numba as nb
import numpy as np

#replacement for the much more costly (-1)**n
@nb.njit()
def sgn(i):
if i%2>0:
return -1.
else:
return 1.

# with error_model="numpy", turns off the division-by-zero checks
#
# fastmath=True makes SIMD-vectorization in this case possible
# floating point math is in general not commutative
# e.g. calculating four times sgn(i)/(2*i + 1) at once and then the sum
# is not exactly the same as doing this sequentially, therefore you have to
# explicitly allow the compiler to make the optimizations

@nb.njit(fastmath=True,error_model="numpy",cache=True)
def Leibniz_pi(n):
nth_partial_sum = 0. #initialize the variable
for i in range(n+1):
nth_partial_sum += sgn(i)/(2*i + 1)
return nth_partial_sum

%timeit Leibniz_pi(999)
777 ns ± 5.36 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

关于python - 执行数学 sigma 和的最快、最有效和 pythonic 方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56015659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com