python - scipy.special.binom 和 scipy.misc.comb 有什么区别?

标签 python scipy

scipy.special.binom 和 scipy.misc.comb 有什么区别?

在 ipython 中,我可以看到它们返回不同的类型并且具有不同的准确性。

scipy.special.binom(4,3)
4.0

scipy.misc.comb(4,3)
array(4.000000000000001)

然而,他们究竟在做什么不同?

看着 https://github.com/scipy/scipy/blob/master/scipy/special/generate_ufuncs.py , scipy.special.binom 说
binom -- binom: dd->d                                      -- orthogonal_eval.pxd

scipy.misc.comb 调用 scipy.special.gammaln,其在 generate_ufuncs.py 中的行说
gammaln -- lgam: d->d, clngamma_wrap: D->D                 -- cephes.h, specfun_wrappers.h

最佳答案

每当您遇到不知道某些代码在做什么并且在某个解释器中简单地导入父模块并检查代码的执行、文档字符串等并不容易的情况时,那么您有一些选项。

让我来描述两个选项,这两个选项这次结果不是很有帮助,但它们是将来开始解决此类问题的好方法(以便您可以包含这些尝试的输出,以向人们证明您尝试过在这里发布之前的一些东西,并且看起来很喜欢知道这些东西是什么):

您可以使用 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)')"

如果使用 *nix 操作系统,您也可以(几乎总是)使用 strace启动一些东西并检查所进行的系统调用。在这种情况下,您可以查看输出
strace -qc python -c "from scipy import special; special.binom(4,3)"

相对
strace -qc python -c "from scipy import misc; special.comb(4,3)"

(-qc 选项使输出不那么冗长,并汇总了在不同系统调用中花费的时间,这在第一次启动时可以更容易阅读。如果您省略 -qc 部分,您将获得大屏幕转储所有的系统调用……你想在 Emacs 中打开并搜索的东西,或者通过管道连接到系统工具进行搜索)。

在这种情况下,strace没有太大帮助,并且有很多与模块导入相关的嘈杂系统调用。

这次对我有用的是cProfile :
python -c "import cProfile; cProfile.run('from scipy import special; special.binom(4,3)')"

在这种情况下,我能够看到第一次执行归结为对 scipy.special.orthogonal_eval 的系统调用。谷歌搜索这个模块发现我们正在谈论一个共享库,构建为文件 orthogonal_eval.so我发现了这个 nice page with the source code .

你可以看到binom的完整函数定义在那里,其中包括对小值公式中涉及的阶乘的标准计算,以及与其他特殊函数的一些近似值(我看到一些名为 cephes.h 的文件中定义的对“Gamma”、“beta”和“lbeta”的调用) )。

看起来很标准——如果我需要的话,我可以去挖掘一下 .h文件和谷歌更多一些,可能会在所有这些的底部找到一个长期存在的特殊函数的 C 库。

同时,对于 misc.comb首先考虑regular documentation这是可用的(而对我来说,它不适用于 binom )。

文档字符串表示可能存在第三个参数,exact如果您不想要 float,可以将其设置为 0 以外的值。被退回。在这种情况下,long已返回,但您可以转换为 int如果你愿意。

这就解释了精度问题。您可以阅读 orthogonal_eval怎么样k相对较小,答案将给出一个整数(整数参数),然后使用舍入误差较小的东西。而comb只有在你说 exact=1 时才会这样做(或其他任何东西,例如 exact != 0 )。

至于comb的代码正在执行,好吧,我们可以 view the source这是从 SciPy 文档页面链接的。

该函数还利用了来自 scipy.special 的一些辅助函数调用。但是 Python 层和 C 层中调用的混合是不同的,并且近似部分的实现也略有不同。

我不确定您需要什么级别的特异性,但我想说,对于大多数用途,这种级别的详细信息应该足够了:binom直接在 orthogonal_eval 中的 C 扩展层中实现并进行一些调整以减少小输入的精度问题。 misc直接在Python中实现小输入的东西并利用special调用不经过 binom本身——所以对于编程这些的人来说,有一定程度的重新发明轮子。由于它们在 Python 层和 C 层之间混合和匹配函数调用,因此存在一些精度差异也就不足为奇了。

关于python - scipy.special.binom 和 scipy.misc.comb 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21535852/

相关文章:

python - 为什么在使用 Anaconda 启动期间运行 virt-install BASH 脚本与使用 Python 的 subprocess.run() 函数会出现不一致?

python - 与 Arduino 的串行通信仅在屏幕运行时有效

python - scipy.optimize.minimize 与 BFGS : Objective called twice with same parameter vector

python - 无法使用 pickle 和多个模块加载文件

python - 在使用 django-filter 进行过滤时如何将过滤后的值导出到 csv 文件中

python - 从 Haskell 调用 Sage

python - Pandas:如何构建需要先前输出作为输入的行式应用

python - 有没有连接 scipy.sparse 矩阵的有效方法?

python - 如何在 linregress scipy 中使用数据帧中的日期时间字段?

python - 最小二乘拟合,混淆python scipy的赋值查询