<p>如果您愿意将该函数移到cython并添加一些类型注释,那么将获得显著的性能提升。这是我的算法版本:</p>
<p>你知道吗阿彭.pyx地址:</p>
<pre><code>cimport cython
from libc.math cimport fabs, log
import numpy as np
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.initializedcheck(False)
@cython.cdivision(True)
cdef double max_dist(double[:] x_i, double[:] x_j, int m) nogil:
#Performs the max function described in step 4 of ApEn algorithm
cdef double out
cdef double dist
out = fabs(x_i[0] - x_j[0])
for k in range(1, m - 1):
dist = fabs(x_i[k] - x_j[k])
if dist > out:
out = dist
return out
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.initializedcheck(False)
@cython.cdivision(True)
cdef double phi(double[:] Sn, int m, int r):
cdef int N = len(Sn)
cdef int i
cdef int j
cdef int k
cdef int c_val
cdef int counter
cdef double phi_sum = 0
cdef double phi
cdef double m_dist
#Performs step 3 of the ApEn algorithm
cdef double[:, :] x = np.empty((N - m + 1, m), dtype=np.float64)
with nogil:
for i in range(N - m + 1):
for j in range(0, m):
x[i, j] = Sn[j + i]
#Performs a combined steps 4 & 5 of the ApEn algorithm
for i in range(N - m + 1):
counter = 0
for j in range(N - m + 1):
m_dist = max_dist(x[i], x[j], m)
c_val = 1 if m_dist <= r else 0
counter += c_val
phi_sum += log(counter / (N - m + 1.0))
phi = phi_sum / (N - m + 1.0)
return phi
cpdef double approx_entropy(double[:] Sn, int m, int r):#Passing in steps 1 & 2 of the ApEn algorithm
cdef double ApEn = abs(phi(Sn, m, r) - phi(Sn, m + 1, r))#Performs step 6 of the ApEn algorithm
return ApEn
</code></pre>
<p>你知道吗apen.pxd公司地址:</p>
<pre><code>cdef double max_dist(double[:] x_i, double[:] x_j, int m) nogil
cdef double phi(double[:] Sn, int m, int r)
cpdef double approx_entropy(double[:] Sn, int m, int r)
</code></pre>
<p>你知道吗设置.pxd地址:</p>
<pre><code>from distutils.core import setup
from Cython.Build import cythonize
from distutils.core import Extension
import numpy as np
extensions = [
Extension("apen", sources=["apen.pyx"], include_dirs=[np.get_include()], extra_compile_args=["-w"]),
]
setup(
ext_modules = cythonize(extensions)
)
</code></pre>
<p>你知道吗主.py地址:</p>
<pre><code>import time
import apen
import numpy as np
start = time.time()
data = np.random.rand(2000)
#data = np.array([85, 80, 89] * 17, dtype=np.float64)
answer = apen.approx_entropy(Sn=data, m=2, r=3)
print(answer)
end = time.time()
print(end - start)
</code></pre>
<p>用这个代码在我的笔记本电脑上计算2000个随机数据点,cython代码用0.36秒计算ApEn。相比之下,wikipedia代码用14.75秒。这相当于速度提升了40倍。希望这对你有帮助!你知道吗</p>