scipy.misc.comb
'un artık anlık uygulamadan daha hızlı olduğu kesin midir?"scipy.misc.comb" ad hoc bir binom hesaplamasından daha mı hızlı?
eski cevap, Statistics: combinations in Python göre bu homebrew fonksiyon hızlı scipy.misc.comb
daha hesaplanırken kombinasyonlar nCr
geçerli:
def choose(n, k):
"""
A fast way to calculate binomial coefficients by Andrew Dalke (contrib).
"""
if 0 <= k <= n:
ntok = 1
ktok = 1
for t in xrange(1, min(k, n - k) + 1):
ntok *= n
ktok *= t
n -= 1
return ntok // ktok
else:
return 0
Fakat kendi makinede bazı testler çalıştırdıktan sonra, bu vaka gibi görünmüyor Bu komut dosyası kullanarak:
: aşağıdaki çıktı üretmesi olsunfrom scipy.misc import comb
import random, time
def choose(n, k):
"""
A fast way to calculate binomial coefficients by Andrew Dalke (contrib).
"""
if 0 <= k <= n:
ntok = 1
ktok = 1
for t in xrange(1, min(k, n - k) + 1):
ntok *= n
ktok *= t
n -= 1
return ntok // ktok
else:
return 0
def timing(f):
def wrap(*args):
time1 = time.time()
ret = f(*args)
time2 = time.time()
print '%s function took %0.3f ms' % (f.__name__, (time2-time1)*1000.0)
return ret
return wrap
@timing
def test_func(combination_func, nk):
for n,k in nk:
combination_func(n, k)
nk = []
for _ in range(1000):
n = int(random.random() * 10000)
k = random.randint(0,n)
nk.append((n,k))
test_func(comb, nk)
test_func(choose, nk)
$ python test.py
/usr/lib/python2.7/dist-packages/scipy/misc/common.py:295: RuntimeWarning: overflow encountered in exp
vals = exp(lgam(N+1) - lgam(N-k+1) - lgam(k+1))
999
test_func function took 32.869 ms
999
test_func function took 1859.125 ms
$ python test.py
/usr/lib/python2.7/dist-packages/scipy/misc/common.py:295: RuntimeWarning: overflow encountered in exp
vals = exp(lgam(N+1) - lgam(N-k+1) - lgam(k+1))
999
test_func function took 32.265 ms
999
test_func function took 1878.550 ms
Zaman profili oluşturma testi, yeni scipy.misc.comb
'un, geçici choose()
işlevinden daha hızlı olduğunu gösterdi mi? Test komutumda zamanlamayı yanlış yapan herhangi bir hata var mı?
Neden scipy.misc.comb
şimdi daha hızlıdır? Bazı cython
/c
kaydırma hileleri yüzünden mi?
@WarrenWeckesser yorumunun ardından
EDITED:scipy.misc.comb()
kullanırken noktası yaklastırmasını yüzen varsayılan kullanarak, çünkü kayan nokta taşması nedeniyle hesaplama sonları. üzerinden
@timing
def test_func(combination_func, nk):
for i, (n,k) in enumerate(nk):
combination_func(n, k, exact=True)
[:
1000 kombinasyonlar hesaplanırken
yerine aşağıdaki fonksiyonunu kullanarak kayan nokta uzun tamsayı ile hesaplarexact=True
ile test
, bu çok daha yavaş (belgelerine http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.misc.comb.html bakınız) ]:
$ python test.py
test_func function took 3312.211 ms
test_func function took 1764.523 ms
$ python test.py
test_func function took 3320.198 ms
test_func function took 1782.280 ms
Varsayılan olarak, scipy'nin "tarağı" kayan nokta değerini hesaplar; bu, bağımsız değişkenler yeterince büyük olduğunda bir yaklaşım olur. Zamanlamayı, 'tarak' içindeki 'true = True' argümanını kullanarak karşılaştırmalısınız. –
Wow, 'exact = True' kullanıldıktan sonra uber yavaş. Yani 'scipy.misc.comb' yerine ad-hoc işlevini kullanmamak için herhangi bir neden var – alvas
İyi soru! Motive edilmiş hissederseniz, https: // github ile alakalı görünen herhangi bir yorum ekleyebilirsiniz.com/scipy/scipy/issues/3449 –