В чем разница между 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, неудивительно, что будут некоторые различия в точности.