你检查过
中的代码吗
.../scipy/stats/distributions.py?
看起来norm_pdf 最终使用
_norm_pdf_C = math.sqrt(2*pi)
_norm_pdf_logC = math.log(_norm_pdf_C)
def _norm_pdf(x):
return exp(-x**2/2.0) / _norm_pdf_C
由于它不涉及通过 numpy 数组的循环,它看起来不像是 cython 加速的主要候选者。你会写得不一样吗?
哎呀,对不起。你问的是这样的功能:
def pdf(self,x,*args,**kwds):
args, loc, scale = self._parse_args(*args, **kwds)
x,loc,scale = map(asarray,(x,loc,scale))
args = tuple(map(asarray,args))
x = asarray((x-loc)*1.0/scale)
cond0 = self._argcheck(*args) & (scale > 0)
cond1 = (scale > 0) & (x >= self.a) & (x <= self.b)
cond = cond0 & cond1
output = zeros(shape(cond),'d')
putmask(output,(1-cond0)+np.isnan(x),self.badvalue)
if any(cond):
goodargs = argsreduce(cond, *((x,)+args+(scale,)))
scale, goodargs = goodargs[-1], goodargs[:-1]
place(output,cond,self._pdf(*goodargs) / scale)
if output.ndim == 0:
return output[()]
return output
除了使用map 进行参数检查和按摩之外,我还看到putmask 和place 中隐藏了一些迭代。我没有经常使用place,但我认为它正在迭代cond,并应用self._pdf,并将值放入output。我怀疑代码组织旨在提供很大的灵活性,允许不同的模型和分布。我没有看到针对速度的严格代码。
对于将受益于转换为cython 的代码,您可能需要从头开始编写一些东西,这些东西不会调用很多其他numpy 和scipy 代码,并且不构建复杂的类结构。专注于一个非常具体的计算,而不是一系列计算。