В чем разница между scipy.специальный.Бином и Сципион.разное.расческа?

в чем разница между scipy.специальный.Бином и Сципион.разное.расческа?

в 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.специальный.бином говорит

binom -- binom: dd->d                                      -- orthogonal_eval.pxd

scipy.разное.расческа зовет скипи.специальный.gammaln, чьи очередь generate_ufuncs.py говорит

gammaln -- lgam: d->d, clngamma_wrap: D->D                 -- cephes.h, specfun_wrappers.h

1 ответов


всякий раз, когда вы сталкиваетесь с ситуацией, когда вы не знаете, что делает какой-то код, и не просто импортировать Родительский модуль в какой-то интерпретатор и проверить выполнение кода, docstrings и т. д. тогда у вас есть несколько вариантов.

позвольте мне описать два варианта, которые на этот раз не оказались очень полезными, но которые являются отличным способом начать с такого вопроса в будущем (так что вы можете включить вывод из этих попытки доказать людям, что вы пробовали некоторые вещи перед публикацией здесь, и выглядеть причудливо, зная, что это такое):

вы можете использовать dis модуль для разборки кода Python на выполненные op-коды, например:

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 OS, вы также можете (почти всегда) использовать 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)"

(the -qc опция делает вывод менее болтливым и агрегирует время, проведенное в различных системных вызовах, которые могут быть легче читать в качестве первого запуска. Если вы опустите -qc часть, вы получите большой экран дампа всех системных вызовов... что-то, что вы хотите открыть в Emacs и выполнить поиск или передать системному инструменту для поиска).

в этом случае strace не помогает слишком много, и есть много шума системные вызовы, связанные только с импортом модулей.

то, что сработало для меня на этот раз, это cProfile:

python -c "import cProfile; cProfile.run('from scipy import special; special.binom(4,3)')"

в этом случае, я смог увидеть, что первое исполнение сводится к системному вызову в scipy.special.orthogonal_eval и Googling этот модуль показал, что мы говорим об общей библиотеке, построенной как файл orthogonal_eval.so и я нашел это хорошая страница с исходным кодом.

вы можете увидеть полное определение функции binom там, который включает в себя стандартный расчет факториалов, участвующих в Формуле для малых значений, и некоторое приближение с другими специальными функциями (я вижу некоторые вызовы "гамма", "бета" и "lbeta", определенные в некотором файле под названием cephes.h).

выглядит довольно стандартно, если мне нужно, я могу пойти покопаться, что .h файл и Google еще и, вероятно, найти давнюю библиотеку C специальных функций в нижней части всего этого.

между тем, для misc.comb сначала рассмотрим, что регулярный документация из этого доступно (тогда как, для меня, оно не доступно для binom).

docstring говорит, что существует возможный 3-й аргумент,exact который может быть установлен на что-то другое, чем 0, если вы не хочу float подлежит возврату. В этом случае long возвращается, но вы можете бросить в 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, неудивительно, что будут некоторые различия в точности.