我注意到,n阶的^{jv(n,x)
在x中矢量化:
In [14]: import scipy.special as sp
In [16]: sp.jv(1, range(3)) # n=1, [x=0,1,2]
Out[16]: array([ 0., 0.44005059, 0.57672481])
但是球面贝塞尔函数没有相应的矢量化形式,sp.sph_jn
:
In [19]: sp.sph_jn(1,range(3))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-19-ea59d2f45497> in <module>()
----> 1 sp.sph_jn(1,range(3)) #n=1, 3 value array
/home/glue/anaconda/envs/fibersim/lib/python2.7/site-packages/scipy/special/basic.pyc in sph_jn(n, z)
262 """
263 if not (isscalar(n) and isscalar(z)):
--> 264 raise ValueError("arguments must be scalars.")
265 if (n != floor(n)) or (n < 0):
266 raise ValueError("n must be a non-negative integer.")
ValueError: arguments must be scalars.
此外,球面贝塞尔函数一次计算N的所有阶数。因此,如果我想要n=5
贝塞尔函数作为参数x=10
,它将返回n=1,2,3,4,5。它实际上在一个过程中返回jn及其派生:
为什么API中存在这种不对称性,有人知道有一个库可以返回矢量化的球形贝塞尔函数,或者至少更快(例如在cython中)?在
您可以编写一个cython函数来加速计算,首先要做的是获得fortran函数
SPHJ
的地址,下面是如何在Python中执行此操作:然后可以在Cython中直接调用fortran函数,注意我使用
^{pr2}$prange()
来使用多核来加速计算:比较一下,下面是在forloop中调用
sphj()
的Python函数:以下是10个元素的%timit结果:
结果是:
以下是100000个元素的结果:
结果是:
有一个pull request将矢量化球面贝塞尔函数例程合并到SciPy as
scipy.special.spherical_x
,其中x = jn, yn, in, kn
。如果运气好的话,他们应该会把它放到0.18.0版本中。在相对于
np.vectorize
(即for循环)的性能改进取决于函数,但可以是数量级的。在如果有人还感兴趣的话,我找到了一个比特德·普利克(Ted Pudlik)快17倍的解决方案。我使用的事实是,n阶球面贝塞尔函数本质上是n阶标准贝塞尔函数的1/sqrt(x)乘以已经矢量化的n+1/2阶标准贝塞尔函数:
我得到了以下时间安排:
^{pr2}$相关问题 更多 >
编程相关推荐