scipy.special.binom和scipy.misc.comb有什么区别?
在ipython中,我可以看到它们返回不同的类型,并且具有不同的准确性.
scipy.special.binom(4,3)
4.0
scipy.misc.comb(4,3)
array(4.000000000000001)
Run Code Online (Sandbox Code Playgroud)
然而他们到底做了什么不同?
看看https://github.com/scipy/scipy/blob/master/scipy/special/generate_ufuncs.py,scipy.special.binom说
binom -- binom: dd->d -- orthogonal_eval.pxd
Run Code Online (Sandbox Code Playgroud)
scipy.misc.comb调用scipy.special.gammaln,其行在generate_ufuncs.py中表示
gammaln -- lgam: d->d, clngamma_wrap: D->D -- cephes.h, specfun_wrappers.h
Run Code Online (Sandbox Code Playgroud)
ely*_*ely 11
每当遇到一些你不知道某些代码正在做什么的情况时,简单地在一些解释器中导入父模块并检查代码,文档字符串等的执行情况并不容易,那么你有几个选项.
让我描述两个选项,这次没有变得非常有用,但这是一个很好的方式来开始这样的问题在未来(这样你可以包括这些尝试的输出,以证明你尝试过的人在发布之前发布的一些内容,并且看起来很想知道这些内容是什么):
您可以使用该dis模块将Python代码反汇编为已执行的操作码,如下所示:
python -c "import dis; from scipy import misc; print dis.dis('misc.comb(4,3)')"
python -c "import dis; from scipy import special; print dis.dis('special.binom(4,3)')"
Run Code Online (Sandbox Code Playgroud)
如果使用*nix OS,您也可以(几乎总是)使用strace启动某些内容并检查所进行的系统调用.在这种情况下,您可以查看输出
strace -qc python -c "from scipy import special; special.binom(4,3)"
Run Code Online (Sandbox Code Playgroud)
与
strace -qc python -c "from scipy import misc; special.comb(4,3)"
Run Code Online (Sandbox Code Playgroud)
(该-qc选项使输出不那么繁琐,并聚合在不同系统调用中花费的时间,这可以更容易阅读作为第一次启动.如果省略该-qc部分,您将获得所有系统调用的大屏幕转储.你想在Emacs中打开并搜索或管道到系统工具进行搜索的东西.
在这种情况下,strace没有太多帮助,并且有很多与模块导入相关的嘈杂系统调用.
这次对我有用的是cProfile:
python -c "import cProfile; cProfile.run('from scipy import special; special.binom(4,3)')"
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我能够看到第一次执行归结为系统调用scipy.special.orthogonal_eval和Googling这个模块显示我们正在谈论一个共享库,构建为文件orthogonal_eval.so,我发现这个带有源代码的好页面.
您可以看到binom那里的完整函数定义,其中包括小值公式中涉及的阶乘的标准计算,以及与其他特殊函数的一些近似(我看到一些调用"Gamma","beta"和"lbeta")在某个文件中定义了cephes.h).
看起来非常标准 - 如果我需要,我可以去挖掘那个.h文件和谷歌更多,并可能在所有这些的底部找到一个长期存在的特殊功能库.
同时,misc.comb首先要考虑到这个的常规文档是可用的(而对我来说,它是不可用的binom).
文档字符串说,有一个可能的第三个参数,exact它可以被设置为0以外的东西,如果你不做希望float归还.在这种情况下,long返回a,但int如果你愿意,你可以投出.
这解释了精确度问题.你可以读orthogonal_eval一下如果k相对较小,答案将给出一个整数(整数参数),然后使用具有较小舍入误差的东西.然而,comb只有当你说exact=1(或其他任何类似的东西exact != 0)时才会这样做.
至于comb正在执行的代码,我们可以查看从SciPy文档页面链接的源代码.
这个函数也使用了一些辅助函数调用,scipy.special但是Python层和C层调用的函数之间的混合是不同的,并且近似部分的实现也略有不同.
我不确定你需要什么级别的特异性,但我想说,对于大多数用途,这个细节水平应该足够了:binom直接在C扩展层中实现orthogonal_eval并进行一些调整以减少小输入的精度问题.misc直接在Python中实现小输入内容并利用special调用而不通过binom自身 - 所以对于编程这些内容的人来说,有一些重新发明的轮子.由于它们混合并匹配Python层和C层之间的函数调用,因此存在一些精度差异并不奇怪.
| 归档时间: |
|
| 查看次数: |
2347 次 |
| 最近记录: |