私はnumba
でコンパイルしたい関数を持っていますが、その関数内で階乗を計算する必要があります。残念ながらnumba
はmath.factorial
をサポートしていません:numba nopython関数の階乗を計算する最速の方法
import math
import numba as nb
@nb.njit
def factorial1(x):
return math.factorial(x)
factorial1(10)
# UntypedAttributeError: Failed at nopython (nopython frontend)
私はそれはそれは「整数値を表す浮動小数点数を返さない本当のmath.gamma
機能にしかし反対に、(階乗を計算するのに使用することができる)math.gamma
をサポートすることを見ました「:
@nb.njit
def factorial2(x):
return math.gamma(x+1)
factorial2(10)
# 3628799.9999999995 <-- not exact
math.gamma(11)
# 3628800.0 <-- exact
、それはmath.factorial
に比べて遅いです:
%timeit factorial2(10)
# 1.12 µs ± 11.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit math.factorial(10)
# 321 ns ± 6.12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
は、だから私は自分自身の関数を定義することにしました:
@nb.njit
def factorial3(x):
n = 1
for i in range(2, x+1):
n *= i
return n
factorial3(10)
# 3628800
%timeit factorial3(10)
# 821 ns ± 12.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
それはまだmath.factorial
より遅いのですが、それはmath.gamma
ベースnumba機能よりも高速だし、値が「正確」です。
したがって、nopython numba関数の内部で、正の整数(< = 20;オーバーフローを避けるため)のfactorial
を計算する最速の方法を探しています。
整数「0..20」の階乗だけに関係する場合、ルックアップテーブルはおそらく速度のチェックに値するでしょう。 –
Arrrgggh、前回のコメントであなたの書いた*あなたが*書いたはずです*。または*あなたの唯一の関心事は... * –
numbaでpythonのアプローチを再実装することができます - それは特別な方法で乗算を注文するいくつかの追加ステップを経ます - https://github.com/python/ cbathon/blob/3.6/Modules/mathmodule.c#L1275 – chrisb