使用 Python 和 Numpy 高效计算阶乘
Computing factorials efficiently with Python and Numpy
在 python / numpy - 有没有办法构建包含阶乘的表达式 - 但由于在我的场景中,许多阶乘将被复制或减少,等到我指示 运行 时间计算它。
假设 F(x) := x!
然后我构建了一个像 (F(6) + F(7)) / F(4)
这样的表达式 - 我可以大大加快这个过程,甚至可以通过
在脑海中完成
(F(6) * (1 + 7)) / F(4)
= 5 * 6 * 8
= 240
基本上,我将生成这样的表达式,并希望计算机更智能,而不是通过乘以 1 来计算所有阶乘,即使用我的示例实际上不会
(6*5*4*3*2 + 7*6*5*4*3*2) / 4*3*2
我实际上已经开始开发阶乘 class,但我是 python 和 numpy 的新手,想知道这是否是一个已经解决的问题。
如果 space 效率不是主要问题,也许您可以考虑使用 table 查找来提高效率。会大大减少重复计算的次数。以下不是非常有效,但这是基本思想。
cache = {1:1}
def cached_factorial(n):
if (n in cache):
return cache[n]
else:
result = n * cached_factorial(n-1)
cache[n] = result
return result
正如@Oleg 所建议的那样,您可以使用 sympy 执行此操作:
import numpy as np
import sympy as sp
# preparation
n = sp.symbols("n")
F = sp.factorial
# create the equation
f = (F(n) + F(n + 1)) / F(n - 2)
print(f) # => (factorial(n) + factorial(n + 1))/factorial(n - 2)
# reduce it
f = f.simplify()
print(f) # => n*(n - 1)*(n + 2)
# evaluate it in SymPy
# Note: very slow!
print(f.subs(n, 6)) # => 240
# turn it into a numpy function
# Note: much faster!
f = sp.lambdify(n, f, "numpy")
a = np.arange(2, 10)
print(f(a)) # => [ 8 30 72 140 240 378 560 792]
在 python / numpy - 有没有办法构建包含阶乘的表达式 - 但由于在我的场景中,许多阶乘将被复制或减少,等到我指示 运行 时间计算它。
假设 F(x) := x!
然后我构建了一个像 (F(6) + F(7)) / F(4)
这样的表达式 - 我可以大大加快这个过程,甚至可以通过
(F(6) * (1 + 7)) / F(4)
= 5 * 6 * 8
= 240
基本上,我将生成这样的表达式,并希望计算机更智能,而不是通过乘以 1 来计算所有阶乘,即使用我的示例实际上不会
(6*5*4*3*2 + 7*6*5*4*3*2) / 4*3*2
我实际上已经开始开发阶乘 class,但我是 python 和 numpy 的新手,想知道这是否是一个已经解决的问题。
如果 space 效率不是主要问题,也许您可以考虑使用 table 查找来提高效率。会大大减少重复计算的次数。以下不是非常有效,但这是基本思想。
cache = {1:1}
def cached_factorial(n):
if (n in cache):
return cache[n]
else:
result = n * cached_factorial(n-1)
cache[n] = result
return result
正如@Oleg 所建议的那样,您可以使用 sympy 执行此操作:
import numpy as np
import sympy as sp
# preparation
n = sp.symbols("n")
F = sp.factorial
# create the equation
f = (F(n) + F(n + 1)) / F(n - 2)
print(f) # => (factorial(n) + factorial(n + 1))/factorial(n - 2)
# reduce it
f = f.simplify()
print(f) # => n*(n - 1)*(n + 2)
# evaluate it in SymPy
# Note: very slow!
print(f.subs(n, 6)) # => 240
# turn it into a numpy function
# Note: much faster!
f = sp.lambdify(n, f, "numpy")
a = np.arange(2, 10)
print(f(a)) # => [ 8 30 72 140 240 378 560 792]