scipy 1.16.2__cp314-cp314t-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1530) hide show
  1. scipy/__config__.py +161 -0
  2. scipy/__init__.py +150 -0
  3. scipy/_cyutility.cp314t-win_arm64.lib +0 -0
  4. scipy/_cyutility.cp314t-win_arm64.pyd +0 -0
  5. scipy/_distributor_init.py +18 -0
  6. scipy/_lib/__init__.py +14 -0
  7. scipy/_lib/_array_api.py +931 -0
  8. scipy/_lib/_array_api_compat_vendor.py +9 -0
  9. scipy/_lib/_array_api_no_0d.py +103 -0
  10. scipy/_lib/_bunch.py +229 -0
  11. scipy/_lib/_ccallback.py +251 -0
  12. scipy/_lib/_ccallback_c.cp314t-win_arm64.lib +0 -0
  13. scipy/_lib/_ccallback_c.cp314t-win_arm64.pyd +0 -0
  14. scipy/_lib/_disjoint_set.py +254 -0
  15. scipy/_lib/_docscrape.py +761 -0
  16. scipy/_lib/_elementwise_iterative_method.py +346 -0
  17. scipy/_lib/_fpumode.cp314t-win_arm64.lib +0 -0
  18. scipy/_lib/_fpumode.cp314t-win_arm64.pyd +0 -0
  19. scipy/_lib/_gcutils.py +105 -0
  20. scipy/_lib/_pep440.py +487 -0
  21. scipy/_lib/_sparse.py +41 -0
  22. scipy/_lib/_test_ccallback.cp314t-win_arm64.lib +0 -0
  23. scipy/_lib/_test_ccallback.cp314t-win_arm64.pyd +0 -0
  24. scipy/_lib/_test_deprecation_call.cp314t-win_arm64.lib +0 -0
  25. scipy/_lib/_test_deprecation_call.cp314t-win_arm64.pyd +0 -0
  26. scipy/_lib/_test_deprecation_def.cp314t-win_arm64.lib +0 -0
  27. scipy/_lib/_test_deprecation_def.cp314t-win_arm64.pyd +0 -0
  28. scipy/_lib/_testutils.py +373 -0
  29. scipy/_lib/_threadsafety.py +58 -0
  30. scipy/_lib/_tmpdirs.py +86 -0
  31. scipy/_lib/_uarray/LICENSE +29 -0
  32. scipy/_lib/_uarray/__init__.py +116 -0
  33. scipy/_lib/_uarray/_backend.py +707 -0
  34. scipy/_lib/_uarray/_uarray.cp314t-win_arm64.lib +0 -0
  35. scipy/_lib/_uarray/_uarray.cp314t-win_arm64.pyd +0 -0
  36. scipy/_lib/_util.py +1283 -0
  37. scipy/_lib/array_api_compat/__init__.py +22 -0
  38. scipy/_lib/array_api_compat/_internal.py +59 -0
  39. scipy/_lib/array_api_compat/common/__init__.py +1 -0
  40. scipy/_lib/array_api_compat/common/_aliases.py +727 -0
  41. scipy/_lib/array_api_compat/common/_fft.py +213 -0
  42. scipy/_lib/array_api_compat/common/_helpers.py +1058 -0
  43. scipy/_lib/array_api_compat/common/_linalg.py +232 -0
  44. scipy/_lib/array_api_compat/common/_typing.py +192 -0
  45. scipy/_lib/array_api_compat/cupy/__init__.py +13 -0
  46. scipy/_lib/array_api_compat/cupy/_aliases.py +156 -0
  47. scipy/_lib/array_api_compat/cupy/_info.py +336 -0
  48. scipy/_lib/array_api_compat/cupy/_typing.py +31 -0
  49. scipy/_lib/array_api_compat/cupy/fft.py +36 -0
  50. scipy/_lib/array_api_compat/cupy/linalg.py +49 -0
  51. scipy/_lib/array_api_compat/dask/__init__.py +0 -0
  52. scipy/_lib/array_api_compat/dask/array/__init__.py +12 -0
  53. scipy/_lib/array_api_compat/dask/array/_aliases.py +376 -0
  54. scipy/_lib/array_api_compat/dask/array/_info.py +416 -0
  55. scipy/_lib/array_api_compat/dask/array/fft.py +21 -0
  56. scipy/_lib/array_api_compat/dask/array/linalg.py +72 -0
  57. scipy/_lib/array_api_compat/numpy/__init__.py +28 -0
  58. scipy/_lib/array_api_compat/numpy/_aliases.py +190 -0
  59. scipy/_lib/array_api_compat/numpy/_info.py +366 -0
  60. scipy/_lib/array_api_compat/numpy/_typing.py +30 -0
  61. scipy/_lib/array_api_compat/numpy/fft.py +35 -0
  62. scipy/_lib/array_api_compat/numpy/linalg.py +143 -0
  63. scipy/_lib/array_api_compat/torch/__init__.py +22 -0
  64. scipy/_lib/array_api_compat/torch/_aliases.py +855 -0
  65. scipy/_lib/array_api_compat/torch/_info.py +369 -0
  66. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  67. scipy/_lib/array_api_compat/torch/fft.py +85 -0
  68. scipy/_lib/array_api_compat/torch/linalg.py +121 -0
  69. scipy/_lib/array_api_extra/__init__.py +38 -0
  70. scipy/_lib/array_api_extra/_delegation.py +171 -0
  71. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  72. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  73. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  74. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  75. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  76. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  77. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  78. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  79. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  80. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  81. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  82. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  83. scipy/_lib/array_api_extra/testing.py +359 -0
  84. scipy/_lib/cobyqa/__init__.py +20 -0
  85. scipy/_lib/cobyqa/framework.py +1240 -0
  86. scipy/_lib/cobyqa/main.py +1506 -0
  87. scipy/_lib/cobyqa/models.py +1529 -0
  88. scipy/_lib/cobyqa/problem.py +1296 -0
  89. scipy/_lib/cobyqa/settings.py +132 -0
  90. scipy/_lib/cobyqa/subsolvers/__init__.py +14 -0
  91. scipy/_lib/cobyqa/subsolvers/geometry.py +387 -0
  92. scipy/_lib/cobyqa/subsolvers/optim.py +1203 -0
  93. scipy/_lib/cobyqa/utils/__init__.py +18 -0
  94. scipy/_lib/cobyqa/utils/exceptions.py +22 -0
  95. scipy/_lib/cobyqa/utils/math.py +77 -0
  96. scipy/_lib/cobyqa/utils/versions.py +67 -0
  97. scipy/_lib/decorator.py +399 -0
  98. scipy/_lib/deprecation.py +274 -0
  99. scipy/_lib/doccer.py +366 -0
  100. scipy/_lib/messagestream.cp314t-win_arm64.lib +0 -0
  101. scipy/_lib/messagestream.cp314t-win_arm64.pyd +0 -0
  102. scipy/_lib/pyprima/__init__.py +212 -0
  103. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  104. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  105. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  106. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  107. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  108. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  109. scipy/_lib/pyprima/cobyla/update.py +289 -0
  110. scipy/_lib/pyprima/common/__init__.py +0 -0
  111. scipy/_lib/pyprima/common/_bounds.py +34 -0
  112. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  113. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  114. scipy/_lib/pyprima/common/_project.py +173 -0
  115. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  116. scipy/_lib/pyprima/common/consts.py +47 -0
  117. scipy/_lib/pyprima/common/evaluate.py +99 -0
  118. scipy/_lib/pyprima/common/history.py +38 -0
  119. scipy/_lib/pyprima/common/infos.py +30 -0
  120. scipy/_lib/pyprima/common/linalg.py +435 -0
  121. scipy/_lib/pyprima/common/message.py +290 -0
  122. scipy/_lib/pyprima/common/powalg.py +131 -0
  123. scipy/_lib/pyprima/common/preproc.py +277 -0
  124. scipy/_lib/pyprima/common/present.py +5 -0
  125. scipy/_lib/pyprima/common/ratio.py +54 -0
  126. scipy/_lib/pyprima/common/redrho.py +47 -0
  127. scipy/_lib/pyprima/common/selectx.py +296 -0
  128. scipy/_lib/tests/__init__.py +0 -0
  129. scipy/_lib/tests/test__gcutils.py +110 -0
  130. scipy/_lib/tests/test__pep440.py +67 -0
  131. scipy/_lib/tests/test__testutils.py +32 -0
  132. scipy/_lib/tests/test__threadsafety.py +51 -0
  133. scipy/_lib/tests/test__util.py +641 -0
  134. scipy/_lib/tests/test_array_api.py +322 -0
  135. scipy/_lib/tests/test_bunch.py +169 -0
  136. scipy/_lib/tests/test_ccallback.py +196 -0
  137. scipy/_lib/tests/test_config.py +45 -0
  138. scipy/_lib/tests/test_deprecation.py +10 -0
  139. scipy/_lib/tests/test_doccer.py +143 -0
  140. scipy/_lib/tests/test_import_cycles.py +18 -0
  141. scipy/_lib/tests/test_public_api.py +482 -0
  142. scipy/_lib/tests/test_scipy_version.py +28 -0
  143. scipy/_lib/tests/test_tmpdirs.py +48 -0
  144. scipy/_lib/tests/test_warnings.py +137 -0
  145. scipy/_lib/uarray.py +31 -0
  146. scipy/cluster/__init__.py +31 -0
  147. scipy/cluster/_hierarchy.cp314t-win_arm64.lib +0 -0
  148. scipy/cluster/_hierarchy.cp314t-win_arm64.pyd +0 -0
  149. scipy/cluster/_optimal_leaf_ordering.cp314t-win_arm64.lib +0 -0
  150. scipy/cluster/_optimal_leaf_ordering.cp314t-win_arm64.pyd +0 -0
  151. scipy/cluster/_vq.cp314t-win_arm64.lib +0 -0
  152. scipy/cluster/_vq.cp314t-win_arm64.pyd +0 -0
  153. scipy/cluster/hierarchy.py +4348 -0
  154. scipy/cluster/tests/__init__.py +0 -0
  155. scipy/cluster/tests/hierarchy_test_data.py +145 -0
  156. scipy/cluster/tests/test_disjoint_set.py +202 -0
  157. scipy/cluster/tests/test_hierarchy.py +1238 -0
  158. scipy/cluster/tests/test_vq.py +434 -0
  159. scipy/cluster/vq.py +832 -0
  160. scipy/conftest.py +683 -0
  161. scipy/constants/__init__.py +358 -0
  162. scipy/constants/_codata.py +2266 -0
  163. scipy/constants/_constants.py +369 -0
  164. scipy/constants/codata.py +21 -0
  165. scipy/constants/constants.py +53 -0
  166. scipy/constants/tests/__init__.py +0 -0
  167. scipy/constants/tests/test_codata.py +78 -0
  168. scipy/constants/tests/test_constants.py +83 -0
  169. scipy/datasets/__init__.py +90 -0
  170. scipy/datasets/_download_all.py +71 -0
  171. scipy/datasets/_fetchers.py +225 -0
  172. scipy/datasets/_registry.py +26 -0
  173. scipy/datasets/_utils.py +81 -0
  174. scipy/datasets/tests/__init__.py +0 -0
  175. scipy/datasets/tests/test_data.py +128 -0
  176. scipy/differentiate/__init__.py +27 -0
  177. scipy/differentiate/_differentiate.py +1129 -0
  178. scipy/differentiate/tests/__init__.py +0 -0
  179. scipy/differentiate/tests/test_differentiate.py +694 -0
  180. scipy/fft/__init__.py +114 -0
  181. scipy/fft/_backend.py +196 -0
  182. scipy/fft/_basic.py +1650 -0
  183. scipy/fft/_basic_backend.py +197 -0
  184. scipy/fft/_debug_backends.py +22 -0
  185. scipy/fft/_fftlog.py +223 -0
  186. scipy/fft/_fftlog_backend.py +200 -0
  187. scipy/fft/_helper.py +348 -0
  188. scipy/fft/_pocketfft/LICENSE.md +25 -0
  189. scipy/fft/_pocketfft/__init__.py +9 -0
  190. scipy/fft/_pocketfft/basic.py +251 -0
  191. scipy/fft/_pocketfft/helper.py +249 -0
  192. scipy/fft/_pocketfft/pypocketfft.cp314t-win_arm64.lib +0 -0
  193. scipy/fft/_pocketfft/pypocketfft.cp314t-win_arm64.pyd +0 -0
  194. scipy/fft/_pocketfft/realtransforms.py +109 -0
  195. scipy/fft/_pocketfft/tests/__init__.py +0 -0
  196. scipy/fft/_pocketfft/tests/test_basic.py +1011 -0
  197. scipy/fft/_pocketfft/tests/test_real_transforms.py +505 -0
  198. scipy/fft/_realtransforms.py +706 -0
  199. scipy/fft/_realtransforms_backend.py +63 -0
  200. scipy/fft/tests/__init__.py +0 -0
  201. scipy/fft/tests/mock_backend.py +96 -0
  202. scipy/fft/tests/test_backend.py +98 -0
  203. scipy/fft/tests/test_basic.py +504 -0
  204. scipy/fft/tests/test_fftlog.py +215 -0
  205. scipy/fft/tests/test_helper.py +558 -0
  206. scipy/fft/tests/test_multithreading.py +84 -0
  207. scipy/fft/tests/test_real_transforms.py +247 -0
  208. scipy/fftpack/__init__.py +103 -0
  209. scipy/fftpack/_basic.py +428 -0
  210. scipy/fftpack/_helper.py +115 -0
  211. scipy/fftpack/_pseudo_diffs.py +554 -0
  212. scipy/fftpack/_realtransforms.py +598 -0
  213. scipy/fftpack/basic.py +20 -0
  214. scipy/fftpack/convolve.cp314t-win_arm64.lib +0 -0
  215. scipy/fftpack/convolve.cp314t-win_arm64.pyd +0 -0
  216. scipy/fftpack/helper.py +19 -0
  217. scipy/fftpack/pseudo_diffs.py +22 -0
  218. scipy/fftpack/realtransforms.py +19 -0
  219. scipy/fftpack/tests/__init__.py +0 -0
  220. scipy/fftpack/tests/fftw_double_ref.npz +0 -0
  221. scipy/fftpack/tests/fftw_longdouble_ref.npz +0 -0
  222. scipy/fftpack/tests/fftw_single_ref.npz +0 -0
  223. scipy/fftpack/tests/test.npz +0 -0
  224. scipy/fftpack/tests/test_basic.py +877 -0
  225. scipy/fftpack/tests/test_helper.py +54 -0
  226. scipy/fftpack/tests/test_import.py +33 -0
  227. scipy/fftpack/tests/test_pseudo_diffs.py +388 -0
  228. scipy/fftpack/tests/test_real_transforms.py +836 -0
  229. scipy/integrate/__init__.py +122 -0
  230. scipy/integrate/_bvp.py +1160 -0
  231. scipy/integrate/_cubature.py +729 -0
  232. scipy/integrate/_dop.cp314t-win_arm64.lib +0 -0
  233. scipy/integrate/_dop.cp314t-win_arm64.pyd +0 -0
  234. scipy/integrate/_ivp/__init__.py +8 -0
  235. scipy/integrate/_ivp/base.py +290 -0
  236. scipy/integrate/_ivp/bdf.py +478 -0
  237. scipy/integrate/_ivp/common.py +451 -0
  238. scipy/integrate/_ivp/dop853_coefficients.py +193 -0
  239. scipy/integrate/_ivp/ivp.py +755 -0
  240. scipy/integrate/_ivp/lsoda.py +224 -0
  241. scipy/integrate/_ivp/radau.py +572 -0
  242. scipy/integrate/_ivp/rk.py +601 -0
  243. scipy/integrate/_ivp/tests/__init__.py +0 -0
  244. scipy/integrate/_ivp/tests/test_ivp.py +1287 -0
  245. scipy/integrate/_ivp/tests/test_rk.py +37 -0
  246. scipy/integrate/_lebedev.py +5450 -0
  247. scipy/integrate/_lsoda.cp314t-win_arm64.lib +0 -0
  248. scipy/integrate/_lsoda.cp314t-win_arm64.pyd +0 -0
  249. scipy/integrate/_ode.py +1395 -0
  250. scipy/integrate/_odepack.cp314t-win_arm64.lib +0 -0
  251. scipy/integrate/_odepack.cp314t-win_arm64.pyd +0 -0
  252. scipy/integrate/_odepack_py.py +273 -0
  253. scipy/integrate/_quad_vec.py +674 -0
  254. scipy/integrate/_quadpack.cp314t-win_arm64.lib +0 -0
  255. scipy/integrate/_quadpack.cp314t-win_arm64.pyd +0 -0
  256. scipy/integrate/_quadpack_py.py +1283 -0
  257. scipy/integrate/_quadrature.py +1336 -0
  258. scipy/integrate/_rules/__init__.py +12 -0
  259. scipy/integrate/_rules/_base.py +518 -0
  260. scipy/integrate/_rules/_gauss_kronrod.py +202 -0
  261. scipy/integrate/_rules/_gauss_legendre.py +62 -0
  262. scipy/integrate/_rules/_genz_malik.py +210 -0
  263. scipy/integrate/_tanhsinh.py +1385 -0
  264. scipy/integrate/_test_multivariate.cp314t-win_arm64.lib +0 -0
  265. scipy/integrate/_test_multivariate.cp314t-win_arm64.pyd +0 -0
  266. scipy/integrate/_test_odeint_banded.cp314t-win_arm64.lib +0 -0
  267. scipy/integrate/_test_odeint_banded.cp314t-win_arm64.pyd +0 -0
  268. scipy/integrate/_vode.cp314t-win_arm64.lib +0 -0
  269. scipy/integrate/_vode.cp314t-win_arm64.pyd +0 -0
  270. scipy/integrate/dop.py +15 -0
  271. scipy/integrate/lsoda.py +15 -0
  272. scipy/integrate/odepack.py +17 -0
  273. scipy/integrate/quadpack.py +23 -0
  274. scipy/integrate/tests/__init__.py +0 -0
  275. scipy/integrate/tests/test__quad_vec.py +211 -0
  276. scipy/integrate/tests/test_banded_ode_solvers.py +305 -0
  277. scipy/integrate/tests/test_bvp.py +714 -0
  278. scipy/integrate/tests/test_cubature.py +1375 -0
  279. scipy/integrate/tests/test_integrate.py +840 -0
  280. scipy/integrate/tests/test_odeint_jac.py +74 -0
  281. scipy/integrate/tests/test_quadpack.py +680 -0
  282. scipy/integrate/tests/test_quadrature.py +730 -0
  283. scipy/integrate/tests/test_tanhsinh.py +1171 -0
  284. scipy/integrate/vode.py +15 -0
  285. scipy/interpolate/__init__.py +228 -0
  286. scipy/interpolate/_bary_rational.py +715 -0
  287. scipy/interpolate/_bsplines.py +2469 -0
  288. scipy/interpolate/_cubic.py +973 -0
  289. scipy/interpolate/_dfitpack.cp314t-win_arm64.lib +0 -0
  290. scipy/interpolate/_dfitpack.cp314t-win_arm64.pyd +0 -0
  291. scipy/interpolate/_dierckx.cp314t-win_arm64.lib +0 -0
  292. scipy/interpolate/_dierckx.cp314t-win_arm64.pyd +0 -0
  293. scipy/interpolate/_fitpack.cp314t-win_arm64.lib +0 -0
  294. scipy/interpolate/_fitpack.cp314t-win_arm64.pyd +0 -0
  295. scipy/interpolate/_fitpack2.py +2397 -0
  296. scipy/interpolate/_fitpack_impl.py +811 -0
  297. scipy/interpolate/_fitpack_py.py +898 -0
  298. scipy/interpolate/_fitpack_repro.py +996 -0
  299. scipy/interpolate/_interpnd.cp314t-win_arm64.lib +0 -0
  300. scipy/interpolate/_interpnd.cp314t-win_arm64.pyd +0 -0
  301. scipy/interpolate/_interpolate.py +2266 -0
  302. scipy/interpolate/_ndbspline.py +415 -0
  303. scipy/interpolate/_ndgriddata.py +329 -0
  304. scipy/interpolate/_pade.py +67 -0
  305. scipy/interpolate/_polyint.py +1025 -0
  306. scipy/interpolate/_ppoly.cp314t-win_arm64.lib +0 -0
  307. scipy/interpolate/_ppoly.cp314t-win_arm64.pyd +0 -0
  308. scipy/interpolate/_rbf.py +290 -0
  309. scipy/interpolate/_rbfinterp.py +550 -0
  310. scipy/interpolate/_rbfinterp_pythran.cp314t-win_arm64.lib +0 -0
  311. scipy/interpolate/_rbfinterp_pythran.cp314t-win_arm64.pyd +0 -0
  312. scipy/interpolate/_rgi.py +764 -0
  313. scipy/interpolate/_rgi_cython.cp314t-win_arm64.lib +0 -0
  314. scipy/interpolate/_rgi_cython.cp314t-win_arm64.pyd +0 -0
  315. scipy/interpolate/dfitpack.py +24 -0
  316. scipy/interpolate/fitpack.py +31 -0
  317. scipy/interpolate/fitpack2.py +29 -0
  318. scipy/interpolate/interpnd.py +24 -0
  319. scipy/interpolate/interpolate.py +30 -0
  320. scipy/interpolate/ndgriddata.py +23 -0
  321. scipy/interpolate/polyint.py +24 -0
  322. scipy/interpolate/rbf.py +18 -0
  323. scipy/interpolate/tests/__init__.py +0 -0
  324. scipy/interpolate/tests/data/bug-1310.npz +0 -0
  325. scipy/interpolate/tests/data/estimate_gradients_hang.npy +0 -0
  326. scipy/interpolate/tests/data/gcvspl.npz +0 -0
  327. scipy/interpolate/tests/test_bary_rational.py +368 -0
  328. scipy/interpolate/tests/test_bsplines.py +3754 -0
  329. scipy/interpolate/tests/test_fitpack.py +519 -0
  330. scipy/interpolate/tests/test_fitpack2.py +1431 -0
  331. scipy/interpolate/tests/test_gil.py +64 -0
  332. scipy/interpolate/tests/test_interpnd.py +452 -0
  333. scipy/interpolate/tests/test_interpolate.py +2630 -0
  334. scipy/interpolate/tests/test_ndgriddata.py +308 -0
  335. scipy/interpolate/tests/test_pade.py +107 -0
  336. scipy/interpolate/tests/test_polyint.py +972 -0
  337. scipy/interpolate/tests/test_rbf.py +246 -0
  338. scipy/interpolate/tests/test_rbfinterp.py +534 -0
  339. scipy/interpolate/tests/test_rgi.py +1151 -0
  340. scipy/io/__init__.py +116 -0
  341. scipy/io/_fast_matrix_market/__init__.py +600 -0
  342. scipy/io/_fast_matrix_market/_fmm_core.cp314t-win_arm64.lib +0 -0
  343. scipy/io/_fast_matrix_market/_fmm_core.cp314t-win_arm64.pyd +0 -0
  344. scipy/io/_fortran.py +354 -0
  345. scipy/io/_harwell_boeing/__init__.py +7 -0
  346. scipy/io/_harwell_boeing/_fortran_format_parser.py +316 -0
  347. scipy/io/_harwell_boeing/hb.py +571 -0
  348. scipy/io/_harwell_boeing/tests/__init__.py +0 -0
  349. scipy/io/_harwell_boeing/tests/test_fortran_format.py +74 -0
  350. scipy/io/_harwell_boeing/tests/test_hb.py +70 -0
  351. scipy/io/_idl.py +917 -0
  352. scipy/io/_mmio.py +968 -0
  353. scipy/io/_netcdf.py +1104 -0
  354. scipy/io/_test_fortran.cp314t-win_arm64.lib +0 -0
  355. scipy/io/_test_fortran.cp314t-win_arm64.pyd +0 -0
  356. scipy/io/arff/__init__.py +28 -0
  357. scipy/io/arff/_arffread.py +873 -0
  358. scipy/io/arff/arffread.py +19 -0
  359. scipy/io/arff/tests/__init__.py +0 -0
  360. scipy/io/arff/tests/data/iris.arff +225 -0
  361. scipy/io/arff/tests/data/missing.arff +8 -0
  362. scipy/io/arff/tests/data/nodata.arff +11 -0
  363. scipy/io/arff/tests/data/quoted_nominal.arff +13 -0
  364. scipy/io/arff/tests/data/quoted_nominal_spaces.arff +13 -0
  365. scipy/io/arff/tests/data/test1.arff +10 -0
  366. scipy/io/arff/tests/data/test10.arff +8 -0
  367. scipy/io/arff/tests/data/test11.arff +11 -0
  368. scipy/io/arff/tests/data/test2.arff +15 -0
  369. scipy/io/arff/tests/data/test3.arff +6 -0
  370. scipy/io/arff/tests/data/test4.arff +11 -0
  371. scipy/io/arff/tests/data/test5.arff +26 -0
  372. scipy/io/arff/tests/data/test6.arff +12 -0
  373. scipy/io/arff/tests/data/test7.arff +15 -0
  374. scipy/io/arff/tests/data/test8.arff +12 -0
  375. scipy/io/arff/tests/data/test9.arff +14 -0
  376. scipy/io/arff/tests/test_arffread.py +421 -0
  377. scipy/io/harwell_boeing.py +17 -0
  378. scipy/io/idl.py +17 -0
  379. scipy/io/matlab/__init__.py +66 -0
  380. scipy/io/matlab/_byteordercodes.py +75 -0
  381. scipy/io/matlab/_mio.py +375 -0
  382. scipy/io/matlab/_mio4.py +632 -0
  383. scipy/io/matlab/_mio5.py +901 -0
  384. scipy/io/matlab/_mio5_params.py +281 -0
  385. scipy/io/matlab/_mio5_utils.cp314t-win_arm64.lib +0 -0
  386. scipy/io/matlab/_mio5_utils.cp314t-win_arm64.pyd +0 -0
  387. scipy/io/matlab/_mio_utils.cp314t-win_arm64.lib +0 -0
  388. scipy/io/matlab/_mio_utils.cp314t-win_arm64.pyd +0 -0
  389. scipy/io/matlab/_miobase.py +435 -0
  390. scipy/io/matlab/_streams.cp314t-win_arm64.lib +0 -0
  391. scipy/io/matlab/_streams.cp314t-win_arm64.pyd +0 -0
  392. scipy/io/matlab/byteordercodes.py +17 -0
  393. scipy/io/matlab/mio.py +16 -0
  394. scipy/io/matlab/mio4.py +17 -0
  395. scipy/io/matlab/mio5.py +19 -0
  396. scipy/io/matlab/mio5_params.py +18 -0
  397. scipy/io/matlab/mio5_utils.py +17 -0
  398. scipy/io/matlab/mio_utils.py +17 -0
  399. scipy/io/matlab/miobase.py +16 -0
  400. scipy/io/matlab/streams.py +16 -0
  401. scipy/io/matlab/tests/__init__.py +0 -0
  402. scipy/io/matlab/tests/data/bad_miuint32.mat +0 -0
  403. scipy/io/matlab/tests/data/bad_miutf8_array_name.mat +0 -0
  404. scipy/io/matlab/tests/data/big_endian.mat +0 -0
  405. scipy/io/matlab/tests/data/broken_utf8.mat +0 -0
  406. scipy/io/matlab/tests/data/corrupted_zlib_checksum.mat +0 -0
  407. scipy/io/matlab/tests/data/corrupted_zlib_data.mat +0 -0
  408. scipy/io/matlab/tests/data/debigged_m4.mat +0 -0
  409. scipy/io/matlab/tests/data/japanese_utf8.txt +5 -0
  410. scipy/io/matlab/tests/data/little_endian.mat +0 -0
  411. scipy/io/matlab/tests/data/logical_sparse.mat +0 -0
  412. scipy/io/matlab/tests/data/malformed1.mat +0 -0
  413. scipy/io/matlab/tests/data/miuint32_for_miint32.mat +0 -0
  414. scipy/io/matlab/tests/data/miutf8_array_name.mat +0 -0
  415. scipy/io/matlab/tests/data/nasty_duplicate_fieldnames.mat +0 -0
  416. scipy/io/matlab/tests/data/one_by_zero_char.mat +0 -0
  417. scipy/io/matlab/tests/data/parabola.mat +0 -0
  418. scipy/io/matlab/tests/data/single_empty_string.mat +0 -0
  419. scipy/io/matlab/tests/data/some_functions.mat +0 -0
  420. scipy/io/matlab/tests/data/sqr.mat +0 -0
  421. scipy/io/matlab/tests/data/test3dmatrix_6.1_SOL2.mat +0 -0
  422. scipy/io/matlab/tests/data/test3dmatrix_6.5.1_GLNX86.mat +0 -0
  423. scipy/io/matlab/tests/data/test3dmatrix_7.1_GLNX86.mat +0 -0
  424. scipy/io/matlab/tests/data/test3dmatrix_7.4_GLNX86.mat +0 -0
  425. scipy/io/matlab/tests/data/test_empty_struct.mat +0 -0
  426. scipy/io/matlab/tests/data/test_mat4_le_floats.mat +0 -0
  427. scipy/io/matlab/tests/data/test_skip_variable.mat +0 -0
  428. scipy/io/matlab/tests/data/testbool_8_WIN64.mat +0 -0
  429. scipy/io/matlab/tests/data/testcell_6.1_SOL2.mat +0 -0
  430. scipy/io/matlab/tests/data/testcell_6.5.1_GLNX86.mat +0 -0
  431. scipy/io/matlab/tests/data/testcell_7.1_GLNX86.mat +0 -0
  432. scipy/io/matlab/tests/data/testcell_7.4_GLNX86.mat +0 -0
  433. scipy/io/matlab/tests/data/testcellnest_6.1_SOL2.mat +0 -0
  434. scipy/io/matlab/tests/data/testcellnest_6.5.1_GLNX86.mat +0 -0
  435. scipy/io/matlab/tests/data/testcellnest_7.1_GLNX86.mat +0 -0
  436. scipy/io/matlab/tests/data/testcellnest_7.4_GLNX86.mat +0 -0
  437. scipy/io/matlab/tests/data/testcomplex_4.2c_SOL2.mat +0 -0
  438. scipy/io/matlab/tests/data/testcomplex_6.1_SOL2.mat +0 -0
  439. scipy/io/matlab/tests/data/testcomplex_6.5.1_GLNX86.mat +0 -0
  440. scipy/io/matlab/tests/data/testcomplex_7.1_GLNX86.mat +0 -0
  441. scipy/io/matlab/tests/data/testcomplex_7.4_GLNX86.mat +0 -0
  442. scipy/io/matlab/tests/data/testdouble_4.2c_SOL2.mat +0 -0
  443. scipy/io/matlab/tests/data/testdouble_6.1_SOL2.mat +0 -0
  444. scipy/io/matlab/tests/data/testdouble_6.5.1_GLNX86.mat +0 -0
  445. scipy/io/matlab/tests/data/testdouble_7.1_GLNX86.mat +0 -0
  446. scipy/io/matlab/tests/data/testdouble_7.4_GLNX86.mat +0 -0
  447. scipy/io/matlab/tests/data/testemptycell_5.3_SOL2.mat +0 -0
  448. scipy/io/matlab/tests/data/testemptycell_6.5.1_GLNX86.mat +0 -0
  449. scipy/io/matlab/tests/data/testemptycell_7.1_GLNX86.mat +0 -0
  450. scipy/io/matlab/tests/data/testemptycell_7.4_GLNX86.mat +0 -0
  451. scipy/io/matlab/tests/data/testfunc_7.4_GLNX86.mat +0 -0
  452. scipy/io/matlab/tests/data/testhdf5_7.4_GLNX86.mat +0 -0
  453. scipy/io/matlab/tests/data/testmatrix_4.2c_SOL2.mat +0 -0
  454. scipy/io/matlab/tests/data/testmatrix_6.1_SOL2.mat +0 -0
  455. scipy/io/matlab/tests/data/testmatrix_6.5.1_GLNX86.mat +0 -0
  456. scipy/io/matlab/tests/data/testmatrix_7.1_GLNX86.mat +0 -0
  457. scipy/io/matlab/tests/data/testmatrix_7.4_GLNX86.mat +0 -0
  458. scipy/io/matlab/tests/data/testminus_4.2c_SOL2.mat +0 -0
  459. scipy/io/matlab/tests/data/testminus_6.1_SOL2.mat +0 -0
  460. scipy/io/matlab/tests/data/testminus_6.5.1_GLNX86.mat +0 -0
  461. scipy/io/matlab/tests/data/testminus_7.1_GLNX86.mat +0 -0
  462. scipy/io/matlab/tests/data/testminus_7.4_GLNX86.mat +0 -0
  463. scipy/io/matlab/tests/data/testmulti_4.2c_SOL2.mat +0 -0
  464. scipy/io/matlab/tests/data/testmulti_7.1_GLNX86.mat +0 -0
  465. scipy/io/matlab/tests/data/testmulti_7.4_GLNX86.mat +0 -0
  466. scipy/io/matlab/tests/data/testobject_6.1_SOL2.mat +0 -0
  467. scipy/io/matlab/tests/data/testobject_6.5.1_GLNX86.mat +0 -0
  468. scipy/io/matlab/tests/data/testobject_7.1_GLNX86.mat +0 -0
  469. scipy/io/matlab/tests/data/testobject_7.4_GLNX86.mat +0 -0
  470. scipy/io/matlab/tests/data/testonechar_4.2c_SOL2.mat +0 -0
  471. scipy/io/matlab/tests/data/testonechar_6.1_SOL2.mat +0 -0
  472. scipy/io/matlab/tests/data/testonechar_6.5.1_GLNX86.mat +0 -0
  473. scipy/io/matlab/tests/data/testonechar_7.1_GLNX86.mat +0 -0
  474. scipy/io/matlab/tests/data/testonechar_7.4_GLNX86.mat +0 -0
  475. scipy/io/matlab/tests/data/testscalarcell_7.4_GLNX86.mat +0 -0
  476. scipy/io/matlab/tests/data/testsimplecell.mat +0 -0
  477. scipy/io/matlab/tests/data/testsparse_4.2c_SOL2.mat +0 -0
  478. scipy/io/matlab/tests/data/testsparse_6.1_SOL2.mat +0 -0
  479. scipy/io/matlab/tests/data/testsparse_6.5.1_GLNX86.mat +0 -0
  480. scipy/io/matlab/tests/data/testsparse_7.1_GLNX86.mat +0 -0
  481. scipy/io/matlab/tests/data/testsparse_7.4_GLNX86.mat +0 -0
  482. scipy/io/matlab/tests/data/testsparsecomplex_4.2c_SOL2.mat +0 -0
  483. scipy/io/matlab/tests/data/testsparsecomplex_6.1_SOL2.mat +0 -0
  484. scipy/io/matlab/tests/data/testsparsecomplex_6.5.1_GLNX86.mat +0 -0
  485. scipy/io/matlab/tests/data/testsparsecomplex_7.1_GLNX86.mat +0 -0
  486. scipy/io/matlab/tests/data/testsparsecomplex_7.4_GLNX86.mat +0 -0
  487. scipy/io/matlab/tests/data/testsparsefloat_7.4_GLNX86.mat +0 -0
  488. scipy/io/matlab/tests/data/teststring_4.2c_SOL2.mat +0 -0
  489. scipy/io/matlab/tests/data/teststring_6.1_SOL2.mat +0 -0
  490. scipy/io/matlab/tests/data/teststring_6.5.1_GLNX86.mat +0 -0
  491. scipy/io/matlab/tests/data/teststring_7.1_GLNX86.mat +0 -0
  492. scipy/io/matlab/tests/data/teststring_7.4_GLNX86.mat +0 -0
  493. scipy/io/matlab/tests/data/teststringarray_4.2c_SOL2.mat +0 -0
  494. scipy/io/matlab/tests/data/teststringarray_6.1_SOL2.mat +0 -0
  495. scipy/io/matlab/tests/data/teststringarray_6.5.1_GLNX86.mat +0 -0
  496. scipy/io/matlab/tests/data/teststringarray_7.1_GLNX86.mat +0 -0
  497. scipy/io/matlab/tests/data/teststringarray_7.4_GLNX86.mat +0 -0
  498. scipy/io/matlab/tests/data/teststruct_6.1_SOL2.mat +0 -0
  499. scipy/io/matlab/tests/data/teststruct_6.5.1_GLNX86.mat +0 -0
  500. scipy/io/matlab/tests/data/teststruct_7.1_GLNX86.mat +0 -0
  501. scipy/io/matlab/tests/data/teststruct_7.4_GLNX86.mat +0 -0
  502. scipy/io/matlab/tests/data/teststructarr_6.1_SOL2.mat +0 -0
  503. scipy/io/matlab/tests/data/teststructarr_6.5.1_GLNX86.mat +0 -0
  504. scipy/io/matlab/tests/data/teststructarr_7.1_GLNX86.mat +0 -0
  505. scipy/io/matlab/tests/data/teststructarr_7.4_GLNX86.mat +0 -0
  506. scipy/io/matlab/tests/data/teststructnest_6.1_SOL2.mat +0 -0
  507. scipy/io/matlab/tests/data/teststructnest_6.5.1_GLNX86.mat +0 -0
  508. scipy/io/matlab/tests/data/teststructnest_7.1_GLNX86.mat +0 -0
  509. scipy/io/matlab/tests/data/teststructnest_7.4_GLNX86.mat +0 -0
  510. scipy/io/matlab/tests/data/testunicode_7.1_GLNX86.mat +0 -0
  511. scipy/io/matlab/tests/data/testunicode_7.4_GLNX86.mat +0 -0
  512. scipy/io/matlab/tests/data/testvec_4_GLNX86.mat +0 -0
  513. scipy/io/matlab/tests/test_byteordercodes.py +29 -0
  514. scipy/io/matlab/tests/test_mio.py +1399 -0
  515. scipy/io/matlab/tests/test_mio5_utils.py +179 -0
  516. scipy/io/matlab/tests/test_mio_funcs.py +51 -0
  517. scipy/io/matlab/tests/test_mio_utils.py +45 -0
  518. scipy/io/matlab/tests/test_miobase.py +32 -0
  519. scipy/io/matlab/tests/test_pathological.py +33 -0
  520. scipy/io/matlab/tests/test_streams.py +241 -0
  521. scipy/io/mmio.py +17 -0
  522. scipy/io/netcdf.py +17 -0
  523. scipy/io/tests/__init__.py +0 -0
  524. scipy/io/tests/data/Transparent Busy.ani +0 -0
  525. scipy/io/tests/data/array_float32_1d.sav +0 -0
  526. scipy/io/tests/data/array_float32_2d.sav +0 -0
  527. scipy/io/tests/data/array_float32_3d.sav +0 -0
  528. scipy/io/tests/data/array_float32_4d.sav +0 -0
  529. scipy/io/tests/data/array_float32_5d.sav +0 -0
  530. scipy/io/tests/data/array_float32_6d.sav +0 -0
  531. scipy/io/tests/data/array_float32_7d.sav +0 -0
  532. scipy/io/tests/data/array_float32_8d.sav +0 -0
  533. scipy/io/tests/data/array_float32_pointer_1d.sav +0 -0
  534. scipy/io/tests/data/array_float32_pointer_2d.sav +0 -0
  535. scipy/io/tests/data/array_float32_pointer_3d.sav +0 -0
  536. scipy/io/tests/data/array_float32_pointer_4d.sav +0 -0
  537. scipy/io/tests/data/array_float32_pointer_5d.sav +0 -0
  538. scipy/io/tests/data/array_float32_pointer_6d.sav +0 -0
  539. scipy/io/tests/data/array_float32_pointer_7d.sav +0 -0
  540. scipy/io/tests/data/array_float32_pointer_8d.sav +0 -0
  541. scipy/io/tests/data/example_1.nc +0 -0
  542. scipy/io/tests/data/example_2.nc +0 -0
  543. scipy/io/tests/data/example_3_maskedvals.nc +0 -0
  544. scipy/io/tests/data/fortran-3x3d-2i.dat +0 -0
  545. scipy/io/tests/data/fortran-mixed.dat +0 -0
  546. scipy/io/tests/data/fortran-sf8-11x1x10.dat +0 -0
  547. scipy/io/tests/data/fortran-sf8-15x10x22.dat +0 -0
  548. scipy/io/tests/data/fortran-sf8-1x1x1.dat +0 -0
  549. scipy/io/tests/data/fortran-sf8-1x1x5.dat +0 -0
  550. scipy/io/tests/data/fortran-sf8-1x1x7.dat +0 -0
  551. scipy/io/tests/data/fortran-sf8-1x3x5.dat +0 -0
  552. scipy/io/tests/data/fortran-si4-11x1x10.dat +0 -0
  553. scipy/io/tests/data/fortran-si4-15x10x22.dat +0 -0
  554. scipy/io/tests/data/fortran-si4-1x1x1.dat +0 -0
  555. scipy/io/tests/data/fortran-si4-1x1x5.dat +0 -0
  556. scipy/io/tests/data/fortran-si4-1x1x7.dat +0 -0
  557. scipy/io/tests/data/fortran-si4-1x3x5.dat +0 -0
  558. scipy/io/tests/data/invalid_pointer.sav +0 -0
  559. scipy/io/tests/data/null_pointer.sav +0 -0
  560. scipy/io/tests/data/scalar_byte.sav +0 -0
  561. scipy/io/tests/data/scalar_byte_descr.sav +0 -0
  562. scipy/io/tests/data/scalar_complex32.sav +0 -0
  563. scipy/io/tests/data/scalar_complex64.sav +0 -0
  564. scipy/io/tests/data/scalar_float32.sav +0 -0
  565. scipy/io/tests/data/scalar_float64.sav +0 -0
  566. scipy/io/tests/data/scalar_heap_pointer.sav +0 -0
  567. scipy/io/tests/data/scalar_int16.sav +0 -0
  568. scipy/io/tests/data/scalar_int32.sav +0 -0
  569. scipy/io/tests/data/scalar_int64.sav +0 -0
  570. scipy/io/tests/data/scalar_string.sav +0 -0
  571. scipy/io/tests/data/scalar_uint16.sav +0 -0
  572. scipy/io/tests/data/scalar_uint32.sav +0 -0
  573. scipy/io/tests/data/scalar_uint64.sav +0 -0
  574. scipy/io/tests/data/struct_arrays.sav +0 -0
  575. scipy/io/tests/data/struct_arrays_byte_idl80.sav +0 -0
  576. scipy/io/tests/data/struct_arrays_replicated.sav +0 -0
  577. scipy/io/tests/data/struct_arrays_replicated_3d.sav +0 -0
  578. scipy/io/tests/data/struct_inherit.sav +0 -0
  579. scipy/io/tests/data/struct_pointer_arrays.sav +0 -0
  580. scipy/io/tests/data/struct_pointer_arrays_replicated.sav +0 -0
  581. scipy/io/tests/data/struct_pointer_arrays_replicated_3d.sav +0 -0
  582. scipy/io/tests/data/struct_pointers.sav +0 -0
  583. scipy/io/tests/data/struct_pointers_replicated.sav +0 -0
  584. scipy/io/tests/data/struct_pointers_replicated_3d.sav +0 -0
  585. scipy/io/tests/data/struct_scalars.sav +0 -0
  586. scipy/io/tests/data/struct_scalars_replicated.sav +0 -0
  587. scipy/io/tests/data/struct_scalars_replicated_3d.sav +0 -0
  588. scipy/io/tests/data/test-1234Hz-le-1ch-10S-20bit-extra.wav +0 -0
  589. scipy/io/tests/data/test-44100Hz-2ch-32bit-float-be.wav +0 -0
  590. scipy/io/tests/data/test-44100Hz-2ch-32bit-float-le.wav +0 -0
  591. scipy/io/tests/data/test-44100Hz-be-1ch-4bytes.wav +0 -0
  592. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-early-eof-no-data.wav +0 -0
  593. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-early-eof.wav +0 -0
  594. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-incomplete-chunk.wav +0 -0
  595. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-rf64.wav +0 -0
  596. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes.wav +0 -0
  597. scipy/io/tests/data/test-48000Hz-2ch-64bit-float-le-wavex.wav +0 -0
  598. scipy/io/tests/data/test-8000Hz-be-3ch-5S-24bit.wav +0 -0
  599. scipy/io/tests/data/test-8000Hz-le-1ch-1byte-ulaw.wav +0 -0
  600. scipy/io/tests/data/test-8000Hz-le-2ch-1byteu.wav +0 -0
  601. scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit-inconsistent.wav +0 -0
  602. scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit-rf64.wav +0 -0
  603. scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit.wav +0 -0
  604. scipy/io/tests/data/test-8000Hz-le-3ch-5S-36bit.wav +0 -0
  605. scipy/io/tests/data/test-8000Hz-le-3ch-5S-45bit.wav +0 -0
  606. scipy/io/tests/data/test-8000Hz-le-3ch-5S-53bit.wav +0 -0
  607. scipy/io/tests/data/test-8000Hz-le-3ch-5S-64bit.wav +0 -0
  608. scipy/io/tests/data/test-8000Hz-le-4ch-9S-12bit.wav +0 -0
  609. scipy/io/tests/data/test-8000Hz-le-5ch-9S-5bit.wav +0 -0
  610. scipy/io/tests/data/various_compressed.sav +0 -0
  611. scipy/io/tests/test_fortran.py +264 -0
  612. scipy/io/tests/test_idl.py +483 -0
  613. scipy/io/tests/test_mmio.py +831 -0
  614. scipy/io/tests/test_netcdf.py +550 -0
  615. scipy/io/tests/test_paths.py +93 -0
  616. scipy/io/tests/test_wavfile.py +501 -0
  617. scipy/io/wavfile.py +938 -0
  618. scipy/linalg/__init__.pxd +1 -0
  619. scipy/linalg/__init__.py +236 -0
  620. scipy/linalg/_basic.py +2146 -0
  621. scipy/linalg/_blas_subroutines.h +164 -0
  622. scipy/linalg/_cythonized_array_utils.cp314t-win_arm64.lib +0 -0
  623. scipy/linalg/_cythonized_array_utils.cp314t-win_arm64.pyd +0 -0
  624. scipy/linalg/_cythonized_array_utils.pxd +40 -0
  625. scipy/linalg/_cythonized_array_utils.pyi +16 -0
  626. scipy/linalg/_decomp.py +1645 -0
  627. scipy/linalg/_decomp_cholesky.py +413 -0
  628. scipy/linalg/_decomp_cossin.py +236 -0
  629. scipy/linalg/_decomp_interpolative.cp314t-win_arm64.lib +0 -0
  630. scipy/linalg/_decomp_interpolative.cp314t-win_arm64.pyd +0 -0
  631. scipy/linalg/_decomp_ldl.py +356 -0
  632. scipy/linalg/_decomp_lu.py +401 -0
  633. scipy/linalg/_decomp_lu_cython.cp314t-win_arm64.lib +0 -0
  634. scipy/linalg/_decomp_lu_cython.cp314t-win_arm64.pyd +0 -0
  635. scipy/linalg/_decomp_lu_cython.pyi +6 -0
  636. scipy/linalg/_decomp_polar.py +113 -0
  637. scipy/linalg/_decomp_qr.py +494 -0
  638. scipy/linalg/_decomp_qz.py +452 -0
  639. scipy/linalg/_decomp_schur.py +336 -0
  640. scipy/linalg/_decomp_svd.py +545 -0
  641. scipy/linalg/_decomp_update.cp314t-win_arm64.lib +0 -0
  642. scipy/linalg/_decomp_update.cp314t-win_arm64.pyd +0 -0
  643. scipy/linalg/_expm_frechet.py +417 -0
  644. scipy/linalg/_fblas.cp314t-win_arm64.lib +0 -0
  645. scipy/linalg/_fblas.cp314t-win_arm64.pyd +0 -0
  646. scipy/linalg/_flapack.cp314t-win_arm64.lib +0 -0
  647. scipy/linalg/_flapack.cp314t-win_arm64.pyd +0 -0
  648. scipy/linalg/_lapack_subroutines.h +1521 -0
  649. scipy/linalg/_linalg_pythran.cp314t-win_arm64.lib +0 -0
  650. scipy/linalg/_linalg_pythran.cp314t-win_arm64.pyd +0 -0
  651. scipy/linalg/_matfuncs.py +1050 -0
  652. scipy/linalg/_matfuncs_expm.cp314t-win_arm64.lib +0 -0
  653. scipy/linalg/_matfuncs_expm.cp314t-win_arm64.pyd +0 -0
  654. scipy/linalg/_matfuncs_expm.pyi +6 -0
  655. scipy/linalg/_matfuncs_inv_ssq.py +886 -0
  656. scipy/linalg/_matfuncs_schur_sqrtm.cp314t-win_arm64.lib +0 -0
  657. scipy/linalg/_matfuncs_schur_sqrtm.cp314t-win_arm64.pyd +0 -0
  658. scipy/linalg/_matfuncs_sqrtm.py +107 -0
  659. scipy/linalg/_matfuncs_sqrtm_triu.cp314t-win_arm64.lib +0 -0
  660. scipy/linalg/_matfuncs_sqrtm_triu.cp314t-win_arm64.pyd +0 -0
  661. scipy/linalg/_misc.py +191 -0
  662. scipy/linalg/_procrustes.py +113 -0
  663. scipy/linalg/_sketches.py +189 -0
  664. scipy/linalg/_solve_toeplitz.cp314t-win_arm64.lib +0 -0
  665. scipy/linalg/_solve_toeplitz.cp314t-win_arm64.pyd +0 -0
  666. scipy/linalg/_solvers.py +862 -0
  667. scipy/linalg/_special_matrices.py +1322 -0
  668. scipy/linalg/_testutils.py +65 -0
  669. scipy/linalg/basic.py +23 -0
  670. scipy/linalg/blas.py +495 -0
  671. scipy/linalg/cython_blas.cp314t-win_arm64.lib +0 -0
  672. scipy/linalg/cython_blas.cp314t-win_arm64.pyd +0 -0
  673. scipy/linalg/cython_blas.pxd +169 -0
  674. scipy/linalg/cython_blas.pyx +1432 -0
  675. scipy/linalg/cython_lapack.cp314t-win_arm64.lib +0 -0
  676. scipy/linalg/cython_lapack.cp314t-win_arm64.pyd +0 -0
  677. scipy/linalg/cython_lapack.pxd +1528 -0
  678. scipy/linalg/cython_lapack.pyx +12045 -0
  679. scipy/linalg/decomp.py +23 -0
  680. scipy/linalg/decomp_cholesky.py +21 -0
  681. scipy/linalg/decomp_lu.py +21 -0
  682. scipy/linalg/decomp_qr.py +20 -0
  683. scipy/linalg/decomp_schur.py +21 -0
  684. scipy/linalg/decomp_svd.py +21 -0
  685. scipy/linalg/interpolative.py +989 -0
  686. scipy/linalg/lapack.py +1081 -0
  687. scipy/linalg/matfuncs.py +23 -0
  688. scipy/linalg/misc.py +21 -0
  689. scipy/linalg/special_matrices.py +22 -0
  690. scipy/linalg/tests/__init__.py +0 -0
  691. scipy/linalg/tests/_cython_examples/extending.pyx +23 -0
  692. scipy/linalg/tests/_cython_examples/meson.build +34 -0
  693. scipy/linalg/tests/data/carex_15_data.npz +0 -0
  694. scipy/linalg/tests/data/carex_18_data.npz +0 -0
  695. scipy/linalg/tests/data/carex_19_data.npz +0 -0
  696. scipy/linalg/tests/data/carex_20_data.npz +0 -0
  697. scipy/linalg/tests/data/carex_6_data.npz +0 -0
  698. scipy/linalg/tests/data/gendare_20170120_data.npz +0 -0
  699. scipy/linalg/tests/test_basic.py +2074 -0
  700. scipy/linalg/tests/test_batch.py +588 -0
  701. scipy/linalg/tests/test_blas.py +1127 -0
  702. scipy/linalg/tests/test_cython_blas.py +118 -0
  703. scipy/linalg/tests/test_cython_lapack.py +22 -0
  704. scipy/linalg/tests/test_cythonized_array_utils.py +130 -0
  705. scipy/linalg/tests/test_decomp.py +3189 -0
  706. scipy/linalg/tests/test_decomp_cholesky.py +268 -0
  707. scipy/linalg/tests/test_decomp_cossin.py +314 -0
  708. scipy/linalg/tests/test_decomp_ldl.py +137 -0
  709. scipy/linalg/tests/test_decomp_lu.py +308 -0
  710. scipy/linalg/tests/test_decomp_polar.py +110 -0
  711. scipy/linalg/tests/test_decomp_update.py +1701 -0
  712. scipy/linalg/tests/test_extending.py +46 -0
  713. scipy/linalg/tests/test_fblas.py +607 -0
  714. scipy/linalg/tests/test_interpolative.py +232 -0
  715. scipy/linalg/tests/test_lapack.py +3620 -0
  716. scipy/linalg/tests/test_matfuncs.py +1125 -0
  717. scipy/linalg/tests/test_matmul_toeplitz.py +136 -0
  718. scipy/linalg/tests/test_procrustes.py +214 -0
  719. scipy/linalg/tests/test_sketches.py +118 -0
  720. scipy/linalg/tests/test_solve_toeplitz.py +150 -0
  721. scipy/linalg/tests/test_solvers.py +844 -0
  722. scipy/linalg/tests/test_special_matrices.py +636 -0
  723. scipy/misc/__init__.py +6 -0
  724. scipy/misc/common.py +6 -0
  725. scipy/misc/doccer.py +6 -0
  726. scipy/ndimage/__init__.py +174 -0
  727. scipy/ndimage/_ctest.cp314t-win_arm64.lib +0 -0
  728. scipy/ndimage/_ctest.cp314t-win_arm64.pyd +0 -0
  729. scipy/ndimage/_cytest.cp314t-win_arm64.lib +0 -0
  730. scipy/ndimage/_cytest.cp314t-win_arm64.pyd +0 -0
  731. scipy/ndimage/_delegators.py +303 -0
  732. scipy/ndimage/_filters.py +2422 -0
  733. scipy/ndimage/_fourier.py +306 -0
  734. scipy/ndimage/_interpolation.py +1033 -0
  735. scipy/ndimage/_measurements.py +1689 -0
  736. scipy/ndimage/_morphology.py +2634 -0
  737. scipy/ndimage/_nd_image.cp314t-win_arm64.lib +0 -0
  738. scipy/ndimage/_nd_image.cp314t-win_arm64.pyd +0 -0
  739. scipy/ndimage/_ndimage_api.py +16 -0
  740. scipy/ndimage/_ni_docstrings.py +214 -0
  741. scipy/ndimage/_ni_label.cp314t-win_arm64.lib +0 -0
  742. scipy/ndimage/_ni_label.cp314t-win_arm64.pyd +0 -0
  743. scipy/ndimage/_ni_support.py +139 -0
  744. scipy/ndimage/_rank_filter_1d.cp314t-win_arm64.lib +0 -0
  745. scipy/ndimage/_rank_filter_1d.cp314t-win_arm64.pyd +0 -0
  746. scipy/ndimage/_support_alternative_backends.py +84 -0
  747. scipy/ndimage/filters.py +27 -0
  748. scipy/ndimage/fourier.py +21 -0
  749. scipy/ndimage/interpolation.py +22 -0
  750. scipy/ndimage/measurements.py +24 -0
  751. scipy/ndimage/morphology.py +27 -0
  752. scipy/ndimage/tests/__init__.py +12 -0
  753. scipy/ndimage/tests/data/label_inputs.txt +21 -0
  754. scipy/ndimage/tests/data/label_results.txt +294 -0
  755. scipy/ndimage/tests/data/label_strels.txt +42 -0
  756. scipy/ndimage/tests/dots.png +0 -0
  757. scipy/ndimage/tests/test_c_api.py +102 -0
  758. scipy/ndimage/tests/test_datatypes.py +67 -0
  759. scipy/ndimage/tests/test_filters.py +3083 -0
  760. scipy/ndimage/tests/test_fourier.py +187 -0
  761. scipy/ndimage/tests/test_interpolation.py +1491 -0
  762. scipy/ndimage/tests/test_measurements.py +1592 -0
  763. scipy/ndimage/tests/test_morphology.py +2950 -0
  764. scipy/ndimage/tests/test_ni_support.py +78 -0
  765. scipy/ndimage/tests/test_splines.py +70 -0
  766. scipy/odr/__init__.py +131 -0
  767. scipy/odr/__odrpack.cp314t-win_arm64.lib +0 -0
  768. scipy/odr/__odrpack.cp314t-win_arm64.pyd +0 -0
  769. scipy/odr/_add_newdocs.py +34 -0
  770. scipy/odr/_models.py +315 -0
  771. scipy/odr/_odrpack.py +1154 -0
  772. scipy/odr/models.py +20 -0
  773. scipy/odr/odrpack.py +21 -0
  774. scipy/odr/tests/__init__.py +0 -0
  775. scipy/odr/tests/test_odr.py +607 -0
  776. scipy/optimize/__init__.pxd +1 -0
  777. scipy/optimize/__init__.py +460 -0
  778. scipy/optimize/_basinhopping.py +741 -0
  779. scipy/optimize/_bglu_dense.cp314t-win_arm64.lib +0 -0
  780. scipy/optimize/_bglu_dense.cp314t-win_arm64.pyd +0 -0
  781. scipy/optimize/_bracket.py +706 -0
  782. scipy/optimize/_chandrupatla.py +551 -0
  783. scipy/optimize/_cobyla_py.py +297 -0
  784. scipy/optimize/_cobyqa_py.py +72 -0
  785. scipy/optimize/_constraints.py +598 -0
  786. scipy/optimize/_dcsrch.py +728 -0
  787. scipy/optimize/_differentiable_functions.py +835 -0
  788. scipy/optimize/_differentialevolution.py +1970 -0
  789. scipy/optimize/_direct.cp314t-win_arm64.lib +0 -0
  790. scipy/optimize/_direct.cp314t-win_arm64.pyd +0 -0
  791. scipy/optimize/_direct_py.py +280 -0
  792. scipy/optimize/_dual_annealing.py +732 -0
  793. scipy/optimize/_elementwise.py +798 -0
  794. scipy/optimize/_group_columns.cp314t-win_arm64.lib +0 -0
  795. scipy/optimize/_group_columns.cp314t-win_arm64.pyd +0 -0
  796. scipy/optimize/_hessian_update_strategy.py +479 -0
  797. scipy/optimize/_highspy/__init__.py +0 -0
  798. scipy/optimize/_highspy/_core.cp314t-win_arm64.lib +0 -0
  799. scipy/optimize/_highspy/_core.cp314t-win_arm64.pyd +0 -0
  800. scipy/optimize/_highspy/_highs_options.cp314t-win_arm64.lib +0 -0
  801. scipy/optimize/_highspy/_highs_options.cp314t-win_arm64.pyd +0 -0
  802. scipy/optimize/_highspy/_highs_wrapper.py +338 -0
  803. scipy/optimize/_isotonic.py +157 -0
  804. scipy/optimize/_lbfgsb.cp314t-win_arm64.lib +0 -0
  805. scipy/optimize/_lbfgsb.cp314t-win_arm64.pyd +0 -0
  806. scipy/optimize/_lbfgsb_py.py +634 -0
  807. scipy/optimize/_linesearch.py +896 -0
  808. scipy/optimize/_linprog.py +733 -0
  809. scipy/optimize/_linprog_doc.py +1434 -0
  810. scipy/optimize/_linprog_highs.py +422 -0
  811. scipy/optimize/_linprog_ip.py +1141 -0
  812. scipy/optimize/_linprog_rs.py +572 -0
  813. scipy/optimize/_linprog_simplex.py +663 -0
  814. scipy/optimize/_linprog_util.py +1521 -0
  815. scipy/optimize/_lsap.cp314t-win_arm64.lib +0 -0
  816. scipy/optimize/_lsap.cp314t-win_arm64.pyd +0 -0
  817. scipy/optimize/_lsq/__init__.py +5 -0
  818. scipy/optimize/_lsq/bvls.py +183 -0
  819. scipy/optimize/_lsq/common.py +731 -0
  820. scipy/optimize/_lsq/dogbox.py +345 -0
  821. scipy/optimize/_lsq/givens_elimination.cp314t-win_arm64.lib +0 -0
  822. scipy/optimize/_lsq/givens_elimination.cp314t-win_arm64.pyd +0 -0
  823. scipy/optimize/_lsq/least_squares.py +1044 -0
  824. scipy/optimize/_lsq/lsq_linear.py +361 -0
  825. scipy/optimize/_lsq/trf.py +587 -0
  826. scipy/optimize/_lsq/trf_linear.py +249 -0
  827. scipy/optimize/_milp.py +394 -0
  828. scipy/optimize/_minimize.py +1199 -0
  829. scipy/optimize/_minpack.cp314t-win_arm64.lib +0 -0
  830. scipy/optimize/_minpack.cp314t-win_arm64.pyd +0 -0
  831. scipy/optimize/_minpack_py.py +1178 -0
  832. scipy/optimize/_moduleTNC.cp314t-win_arm64.lib +0 -0
  833. scipy/optimize/_moduleTNC.cp314t-win_arm64.pyd +0 -0
  834. scipy/optimize/_nnls.py +96 -0
  835. scipy/optimize/_nonlin.py +1634 -0
  836. scipy/optimize/_numdiff.py +963 -0
  837. scipy/optimize/_optimize.py +4169 -0
  838. scipy/optimize/_pava_pybind.cp314t-win_arm64.lib +0 -0
  839. scipy/optimize/_pava_pybind.cp314t-win_arm64.pyd +0 -0
  840. scipy/optimize/_qap.py +760 -0
  841. scipy/optimize/_remove_redundancy.py +522 -0
  842. scipy/optimize/_root.py +732 -0
  843. scipy/optimize/_root_scalar.py +538 -0
  844. scipy/optimize/_shgo.py +1606 -0
  845. scipy/optimize/_shgo_lib/__init__.py +0 -0
  846. scipy/optimize/_shgo_lib/_complex.py +1225 -0
  847. scipy/optimize/_shgo_lib/_vertex.py +460 -0
  848. scipy/optimize/_slsqp_py.py +603 -0
  849. scipy/optimize/_slsqplib.cp314t-win_arm64.lib +0 -0
  850. scipy/optimize/_slsqplib.cp314t-win_arm64.pyd +0 -0
  851. scipy/optimize/_spectral.py +260 -0
  852. scipy/optimize/_tnc.py +438 -0
  853. scipy/optimize/_trlib/__init__.py +12 -0
  854. scipy/optimize/_trlib/_trlib.cp314t-win_arm64.lib +0 -0
  855. scipy/optimize/_trlib/_trlib.cp314t-win_arm64.pyd +0 -0
  856. scipy/optimize/_trustregion.py +318 -0
  857. scipy/optimize/_trustregion_constr/__init__.py +6 -0
  858. scipy/optimize/_trustregion_constr/canonical_constraint.py +390 -0
  859. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +231 -0
  860. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +584 -0
  861. scipy/optimize/_trustregion_constr/projections.py +411 -0
  862. scipy/optimize/_trustregion_constr/qp_subproblem.py +637 -0
  863. scipy/optimize/_trustregion_constr/report.py +49 -0
  864. scipy/optimize/_trustregion_constr/tests/__init__.py +0 -0
  865. scipy/optimize/_trustregion_constr/tests/test_canonical_constraint.py +296 -0
  866. scipy/optimize/_trustregion_constr/tests/test_nested_minimize.py +39 -0
  867. scipy/optimize/_trustregion_constr/tests/test_projections.py +214 -0
  868. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +645 -0
  869. scipy/optimize/_trustregion_constr/tests/test_report.py +34 -0
  870. scipy/optimize/_trustregion_constr/tr_interior_point.py +361 -0
  871. scipy/optimize/_trustregion_dogleg.py +122 -0
  872. scipy/optimize/_trustregion_exact.py +437 -0
  873. scipy/optimize/_trustregion_krylov.py +65 -0
  874. scipy/optimize/_trustregion_ncg.py +126 -0
  875. scipy/optimize/_tstutils.py +972 -0
  876. scipy/optimize/_zeros.cp314t-win_arm64.lib +0 -0
  877. scipy/optimize/_zeros.cp314t-win_arm64.pyd +0 -0
  878. scipy/optimize/_zeros_py.py +1475 -0
  879. scipy/optimize/cobyla.py +19 -0
  880. scipy/optimize/cython_optimize/__init__.py +133 -0
  881. scipy/optimize/cython_optimize/_zeros.cp314t-win_arm64.lib +0 -0
  882. scipy/optimize/cython_optimize/_zeros.cp314t-win_arm64.pyd +0 -0
  883. scipy/optimize/cython_optimize/_zeros.pxd +33 -0
  884. scipy/optimize/cython_optimize/c_zeros.pxd +26 -0
  885. scipy/optimize/cython_optimize.pxd +11 -0
  886. scipy/optimize/elementwise.py +38 -0
  887. scipy/optimize/lbfgsb.py +23 -0
  888. scipy/optimize/linesearch.py +18 -0
  889. scipy/optimize/minpack.py +27 -0
  890. scipy/optimize/minpack2.py +17 -0
  891. scipy/optimize/moduleTNC.py +19 -0
  892. scipy/optimize/nonlin.py +29 -0
  893. scipy/optimize/optimize.py +40 -0
  894. scipy/optimize/slsqp.py +22 -0
  895. scipy/optimize/tests/__init__.py +0 -0
  896. scipy/optimize/tests/_cython_examples/extending.pyx +43 -0
  897. scipy/optimize/tests/_cython_examples/meson.build +32 -0
  898. scipy/optimize/tests/test__basinhopping.py +535 -0
  899. scipy/optimize/tests/test__differential_evolution.py +1703 -0
  900. scipy/optimize/tests/test__dual_annealing.py +416 -0
  901. scipy/optimize/tests/test__linprog_clean_inputs.py +312 -0
  902. scipy/optimize/tests/test__numdiff.py +885 -0
  903. scipy/optimize/tests/test__remove_redundancy.py +228 -0
  904. scipy/optimize/tests/test__root.py +124 -0
  905. scipy/optimize/tests/test__shgo.py +1164 -0
  906. scipy/optimize/tests/test__spectral.py +226 -0
  907. scipy/optimize/tests/test_bracket.py +896 -0
  908. scipy/optimize/tests/test_chandrupatla.py +982 -0
  909. scipy/optimize/tests/test_cobyla.py +195 -0
  910. scipy/optimize/tests/test_cobyqa.py +252 -0
  911. scipy/optimize/tests/test_constraint_conversion.py +286 -0
  912. scipy/optimize/tests/test_constraints.py +255 -0
  913. scipy/optimize/tests/test_cython_optimize.py +92 -0
  914. scipy/optimize/tests/test_differentiable_functions.py +1025 -0
  915. scipy/optimize/tests/test_direct.py +321 -0
  916. scipy/optimize/tests/test_extending.py +28 -0
  917. scipy/optimize/tests/test_hessian_update_strategy.py +300 -0
  918. scipy/optimize/tests/test_isotonic_regression.py +167 -0
  919. scipy/optimize/tests/test_lbfgsb_hessinv.py +65 -0
  920. scipy/optimize/tests/test_lbfgsb_setulb.py +122 -0
  921. scipy/optimize/tests/test_least_squares.py +986 -0
  922. scipy/optimize/tests/test_linear_assignment.py +116 -0
  923. scipy/optimize/tests/test_linesearch.py +328 -0
  924. scipy/optimize/tests/test_linprog.py +2577 -0
  925. scipy/optimize/tests/test_lsq_common.py +297 -0
  926. scipy/optimize/tests/test_lsq_linear.py +287 -0
  927. scipy/optimize/tests/test_milp.py +459 -0
  928. scipy/optimize/tests/test_minimize_constrained.py +845 -0
  929. scipy/optimize/tests/test_minpack.py +1194 -0
  930. scipy/optimize/tests/test_nnls.py +469 -0
  931. scipy/optimize/tests/test_nonlin.py +572 -0
  932. scipy/optimize/tests/test_optimize.py +3344 -0
  933. scipy/optimize/tests/test_quadratic_assignment.py +455 -0
  934. scipy/optimize/tests/test_regression.py +40 -0
  935. scipy/optimize/tests/test_slsqp.py +645 -0
  936. scipy/optimize/tests/test_tnc.py +345 -0
  937. scipy/optimize/tests/test_trustregion.py +110 -0
  938. scipy/optimize/tests/test_trustregion_exact.py +351 -0
  939. scipy/optimize/tests/test_trustregion_krylov.py +170 -0
  940. scipy/optimize/tests/test_zeros.py +998 -0
  941. scipy/optimize/tnc.py +22 -0
  942. scipy/optimize/zeros.py +26 -0
  943. scipy/signal/__init__.py +316 -0
  944. scipy/signal/_arraytools.py +264 -0
  945. scipy/signal/_czt.py +575 -0
  946. scipy/signal/_delegators.py +568 -0
  947. scipy/signal/_filter_design.py +5893 -0
  948. scipy/signal/_fir_filter_design.py +1458 -0
  949. scipy/signal/_lti_conversion.py +534 -0
  950. scipy/signal/_ltisys.py +3546 -0
  951. scipy/signal/_max_len_seq.py +139 -0
  952. scipy/signal/_max_len_seq_inner.cp314t-win_arm64.lib +0 -0
  953. scipy/signal/_max_len_seq_inner.cp314t-win_arm64.pyd +0 -0
  954. scipy/signal/_peak_finding.py +1310 -0
  955. scipy/signal/_peak_finding_utils.cp314t-win_arm64.lib +0 -0
  956. scipy/signal/_peak_finding_utils.cp314t-win_arm64.pyd +0 -0
  957. scipy/signal/_polyutils.py +172 -0
  958. scipy/signal/_savitzky_golay.py +357 -0
  959. scipy/signal/_short_time_fft.py +2228 -0
  960. scipy/signal/_signal_api.py +30 -0
  961. scipy/signal/_signaltools.py +5309 -0
  962. scipy/signal/_sigtools.cp314t-win_arm64.lib +0 -0
  963. scipy/signal/_sigtools.cp314t-win_arm64.pyd +0 -0
  964. scipy/signal/_sosfilt.cp314t-win_arm64.lib +0 -0
  965. scipy/signal/_sosfilt.cp314t-win_arm64.pyd +0 -0
  966. scipy/signal/_spectral_py.py +2471 -0
  967. scipy/signal/_spline.cp314t-win_arm64.lib +0 -0
  968. scipy/signal/_spline.cp314t-win_arm64.pyd +0 -0
  969. scipy/signal/_spline.pyi +34 -0
  970. scipy/signal/_spline_filters.py +848 -0
  971. scipy/signal/_support_alternative_backends.py +73 -0
  972. scipy/signal/_upfirdn.py +219 -0
  973. scipy/signal/_upfirdn_apply.cp314t-win_arm64.lib +0 -0
  974. scipy/signal/_upfirdn_apply.cp314t-win_arm64.pyd +0 -0
  975. scipy/signal/_waveforms.py +687 -0
  976. scipy/signal/_wavelets.py +29 -0
  977. scipy/signal/bsplines.py +21 -0
  978. scipy/signal/filter_design.py +28 -0
  979. scipy/signal/fir_filter_design.py +21 -0
  980. scipy/signal/lti_conversion.py +20 -0
  981. scipy/signal/ltisys.py +25 -0
  982. scipy/signal/signaltools.py +27 -0
  983. scipy/signal/spectral.py +21 -0
  984. scipy/signal/spline.py +18 -0
  985. scipy/signal/tests/__init__.py +0 -0
  986. scipy/signal/tests/_scipy_spectral_test_shim.py +311 -0
  987. scipy/signal/tests/mpsig.py +122 -0
  988. scipy/signal/tests/test_array_tools.py +111 -0
  989. scipy/signal/tests/test_bsplines.py +365 -0
  990. scipy/signal/tests/test_cont2discrete.py +424 -0
  991. scipy/signal/tests/test_czt.py +221 -0
  992. scipy/signal/tests/test_dltisys.py +599 -0
  993. scipy/signal/tests/test_filter_design.py +4744 -0
  994. scipy/signal/tests/test_fir_filter_design.py +851 -0
  995. scipy/signal/tests/test_ltisys.py +1225 -0
  996. scipy/signal/tests/test_max_len_seq.py +71 -0
  997. scipy/signal/tests/test_peak_finding.py +915 -0
  998. scipy/signal/tests/test_result_type.py +51 -0
  999. scipy/signal/tests/test_savitzky_golay.py +363 -0
  1000. scipy/signal/tests/test_short_time_fft.py +1107 -0
  1001. scipy/signal/tests/test_signaltools.py +4735 -0
  1002. scipy/signal/tests/test_spectral.py +2141 -0
  1003. scipy/signal/tests/test_splines.py +427 -0
  1004. scipy/signal/tests/test_upfirdn.py +322 -0
  1005. scipy/signal/tests/test_waveforms.py +400 -0
  1006. scipy/signal/tests/test_wavelets.py +59 -0
  1007. scipy/signal/tests/test_windows.py +987 -0
  1008. scipy/signal/waveforms.py +20 -0
  1009. scipy/signal/wavelets.py +17 -0
  1010. scipy/signal/windows/__init__.py +52 -0
  1011. scipy/signal/windows/_windows.py +2513 -0
  1012. scipy/signal/windows/windows.py +23 -0
  1013. scipy/sparse/__init__.py +350 -0
  1014. scipy/sparse/_base.py +1613 -0
  1015. scipy/sparse/_bsr.py +880 -0
  1016. scipy/sparse/_compressed.py +1328 -0
  1017. scipy/sparse/_construct.py +1454 -0
  1018. scipy/sparse/_coo.py +1581 -0
  1019. scipy/sparse/_csc.py +367 -0
  1020. scipy/sparse/_csparsetools.cp314t-win_arm64.lib +0 -0
  1021. scipy/sparse/_csparsetools.cp314t-win_arm64.pyd +0 -0
  1022. scipy/sparse/_csr.py +558 -0
  1023. scipy/sparse/_data.py +569 -0
  1024. scipy/sparse/_dia.py +677 -0
  1025. scipy/sparse/_dok.py +669 -0
  1026. scipy/sparse/_extract.py +178 -0
  1027. scipy/sparse/_index.py +444 -0
  1028. scipy/sparse/_lil.py +632 -0
  1029. scipy/sparse/_matrix.py +169 -0
  1030. scipy/sparse/_matrix_io.py +167 -0
  1031. scipy/sparse/_sparsetools.cp314t-win_arm64.lib +0 -0
  1032. scipy/sparse/_sparsetools.cp314t-win_arm64.pyd +0 -0
  1033. scipy/sparse/_spfuncs.py +76 -0
  1034. scipy/sparse/_sputils.py +632 -0
  1035. scipy/sparse/base.py +24 -0
  1036. scipy/sparse/bsr.py +22 -0
  1037. scipy/sparse/compressed.py +20 -0
  1038. scipy/sparse/construct.py +38 -0
  1039. scipy/sparse/coo.py +23 -0
  1040. scipy/sparse/csc.py +22 -0
  1041. scipy/sparse/csgraph/__init__.py +210 -0
  1042. scipy/sparse/csgraph/_flow.cp314t-win_arm64.lib +0 -0
  1043. scipy/sparse/csgraph/_flow.cp314t-win_arm64.pyd +0 -0
  1044. scipy/sparse/csgraph/_laplacian.py +563 -0
  1045. scipy/sparse/csgraph/_matching.cp314t-win_arm64.lib +0 -0
  1046. scipy/sparse/csgraph/_matching.cp314t-win_arm64.pyd +0 -0
  1047. scipy/sparse/csgraph/_min_spanning_tree.cp314t-win_arm64.lib +0 -0
  1048. scipy/sparse/csgraph/_min_spanning_tree.cp314t-win_arm64.pyd +0 -0
  1049. scipy/sparse/csgraph/_reordering.cp314t-win_arm64.lib +0 -0
  1050. scipy/sparse/csgraph/_reordering.cp314t-win_arm64.pyd +0 -0
  1051. scipy/sparse/csgraph/_shortest_path.cp314t-win_arm64.lib +0 -0
  1052. scipy/sparse/csgraph/_shortest_path.cp314t-win_arm64.pyd +0 -0
  1053. scipy/sparse/csgraph/_tools.cp314t-win_arm64.lib +0 -0
  1054. scipy/sparse/csgraph/_tools.cp314t-win_arm64.pyd +0 -0
  1055. scipy/sparse/csgraph/_traversal.cp314t-win_arm64.lib +0 -0
  1056. scipy/sparse/csgraph/_traversal.cp314t-win_arm64.pyd +0 -0
  1057. scipy/sparse/csgraph/_validation.py +66 -0
  1058. scipy/sparse/csgraph/tests/__init__.py +0 -0
  1059. scipy/sparse/csgraph/tests/test_connected_components.py +119 -0
  1060. scipy/sparse/csgraph/tests/test_conversions.py +61 -0
  1061. scipy/sparse/csgraph/tests/test_flow.py +209 -0
  1062. scipy/sparse/csgraph/tests/test_graph_laplacian.py +368 -0
  1063. scipy/sparse/csgraph/tests/test_matching.py +307 -0
  1064. scipy/sparse/csgraph/tests/test_pydata_sparse.py +197 -0
  1065. scipy/sparse/csgraph/tests/test_reordering.py +70 -0
  1066. scipy/sparse/csgraph/tests/test_shortest_path.py +540 -0
  1067. scipy/sparse/csgraph/tests/test_spanning_tree.py +66 -0
  1068. scipy/sparse/csgraph/tests/test_traversal.py +148 -0
  1069. scipy/sparse/csr.py +22 -0
  1070. scipy/sparse/data.py +18 -0
  1071. scipy/sparse/dia.py +22 -0
  1072. scipy/sparse/dok.py +22 -0
  1073. scipy/sparse/extract.py +23 -0
  1074. scipy/sparse/lil.py +22 -0
  1075. scipy/sparse/linalg/__init__.py +148 -0
  1076. scipy/sparse/linalg/_dsolve/__init__.py +71 -0
  1077. scipy/sparse/linalg/_dsolve/_add_newdocs.py +147 -0
  1078. scipy/sparse/linalg/_dsolve/_superlu.cp314t-win_arm64.lib +0 -0
  1079. scipy/sparse/linalg/_dsolve/_superlu.cp314t-win_arm64.pyd +0 -0
  1080. scipy/sparse/linalg/_dsolve/linsolve.py +882 -0
  1081. scipy/sparse/linalg/_dsolve/tests/__init__.py +0 -0
  1082. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +928 -0
  1083. scipy/sparse/linalg/_eigen/__init__.py +22 -0
  1084. scipy/sparse/linalg/_eigen/_svds.py +540 -0
  1085. scipy/sparse/linalg/_eigen/_svds_doc.py +382 -0
  1086. scipy/sparse/linalg/_eigen/arpack/COPYING +45 -0
  1087. scipy/sparse/linalg/_eigen/arpack/__init__.py +20 -0
  1088. scipy/sparse/linalg/_eigen/arpack/_arpack.cp314t-win_arm64.lib +0 -0
  1089. scipy/sparse/linalg/_eigen/arpack/_arpack.cp314t-win_arm64.pyd +0 -0
  1090. scipy/sparse/linalg/_eigen/arpack/arpack.py +1706 -0
  1091. scipy/sparse/linalg/_eigen/arpack/tests/__init__.py +0 -0
  1092. scipy/sparse/linalg/_eigen/arpack/tests/test_arpack.py +717 -0
  1093. scipy/sparse/linalg/_eigen/lobpcg/__init__.py +16 -0
  1094. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +1110 -0
  1095. scipy/sparse/linalg/_eigen/lobpcg/tests/__init__.py +0 -0
  1096. scipy/sparse/linalg/_eigen/lobpcg/tests/test_lobpcg.py +725 -0
  1097. scipy/sparse/linalg/_eigen/tests/__init__.py +0 -0
  1098. scipy/sparse/linalg/_eigen/tests/test_svds.py +886 -0
  1099. scipy/sparse/linalg/_expm_multiply.py +816 -0
  1100. scipy/sparse/linalg/_interface.py +920 -0
  1101. scipy/sparse/linalg/_isolve/__init__.py +20 -0
  1102. scipy/sparse/linalg/_isolve/_gcrotmk.py +503 -0
  1103. scipy/sparse/linalg/_isolve/iterative.py +1051 -0
  1104. scipy/sparse/linalg/_isolve/lgmres.py +230 -0
  1105. scipy/sparse/linalg/_isolve/lsmr.py +486 -0
  1106. scipy/sparse/linalg/_isolve/lsqr.py +589 -0
  1107. scipy/sparse/linalg/_isolve/minres.py +372 -0
  1108. scipy/sparse/linalg/_isolve/tests/__init__.py +0 -0
  1109. scipy/sparse/linalg/_isolve/tests/test_gcrotmk.py +183 -0
  1110. scipy/sparse/linalg/_isolve/tests/test_iterative.py +809 -0
  1111. scipy/sparse/linalg/_isolve/tests/test_lgmres.py +225 -0
  1112. scipy/sparse/linalg/_isolve/tests/test_lsmr.py +185 -0
  1113. scipy/sparse/linalg/_isolve/tests/test_lsqr.py +120 -0
  1114. scipy/sparse/linalg/_isolve/tests/test_minres.py +97 -0
  1115. scipy/sparse/linalg/_isolve/tests/test_utils.py +9 -0
  1116. scipy/sparse/linalg/_isolve/tfqmr.py +179 -0
  1117. scipy/sparse/linalg/_isolve/utils.py +121 -0
  1118. scipy/sparse/linalg/_matfuncs.py +940 -0
  1119. scipy/sparse/linalg/_norm.py +195 -0
  1120. scipy/sparse/linalg/_onenormest.py +467 -0
  1121. scipy/sparse/linalg/_propack/_cpropack.cp314t-win_arm64.lib +0 -0
  1122. scipy/sparse/linalg/_propack/_cpropack.cp314t-win_arm64.pyd +0 -0
  1123. scipy/sparse/linalg/_propack/_dpropack.cp314t-win_arm64.lib +0 -0
  1124. scipy/sparse/linalg/_propack/_dpropack.cp314t-win_arm64.pyd +0 -0
  1125. scipy/sparse/linalg/_propack/_spropack.cp314t-win_arm64.lib +0 -0
  1126. scipy/sparse/linalg/_propack/_spropack.cp314t-win_arm64.pyd +0 -0
  1127. scipy/sparse/linalg/_propack/_zpropack.cp314t-win_arm64.lib +0 -0
  1128. scipy/sparse/linalg/_propack/_zpropack.cp314t-win_arm64.pyd +0 -0
  1129. scipy/sparse/linalg/_special_sparse_arrays.py +949 -0
  1130. scipy/sparse/linalg/_svdp.py +309 -0
  1131. scipy/sparse/linalg/dsolve.py +22 -0
  1132. scipy/sparse/linalg/eigen.py +21 -0
  1133. scipy/sparse/linalg/interface.py +20 -0
  1134. scipy/sparse/linalg/isolve.py +22 -0
  1135. scipy/sparse/linalg/matfuncs.py +18 -0
  1136. scipy/sparse/linalg/tests/__init__.py +0 -0
  1137. scipy/sparse/linalg/tests/propack_test_data.npz +0 -0
  1138. scipy/sparse/linalg/tests/test_expm_multiply.py +367 -0
  1139. scipy/sparse/linalg/tests/test_interface.py +561 -0
  1140. scipy/sparse/linalg/tests/test_matfuncs.py +592 -0
  1141. scipy/sparse/linalg/tests/test_norm.py +154 -0
  1142. scipy/sparse/linalg/tests/test_onenormest.py +252 -0
  1143. scipy/sparse/linalg/tests/test_propack.py +165 -0
  1144. scipy/sparse/linalg/tests/test_pydata_sparse.py +272 -0
  1145. scipy/sparse/linalg/tests/test_special_sparse_arrays.py +337 -0
  1146. scipy/sparse/sparsetools.py +17 -0
  1147. scipy/sparse/spfuncs.py +17 -0
  1148. scipy/sparse/sputils.py +17 -0
  1149. scipy/sparse/tests/__init__.py +0 -0
  1150. scipy/sparse/tests/data/csc_py2.npz +0 -0
  1151. scipy/sparse/tests/data/csc_py3.npz +0 -0
  1152. scipy/sparse/tests/test_arithmetic1d.py +341 -0
  1153. scipy/sparse/tests/test_array_api.py +561 -0
  1154. scipy/sparse/tests/test_base.py +5870 -0
  1155. scipy/sparse/tests/test_common1d.py +447 -0
  1156. scipy/sparse/tests/test_construct.py +872 -0
  1157. scipy/sparse/tests/test_coo.py +1119 -0
  1158. scipy/sparse/tests/test_csc.py +98 -0
  1159. scipy/sparse/tests/test_csr.py +214 -0
  1160. scipy/sparse/tests/test_dok.py +209 -0
  1161. scipy/sparse/tests/test_extract.py +51 -0
  1162. scipy/sparse/tests/test_indexing1d.py +603 -0
  1163. scipy/sparse/tests/test_matrix_io.py +109 -0
  1164. scipy/sparse/tests/test_minmax1d.py +128 -0
  1165. scipy/sparse/tests/test_sparsetools.py +344 -0
  1166. scipy/sparse/tests/test_spfuncs.py +97 -0
  1167. scipy/sparse/tests/test_sputils.py +424 -0
  1168. scipy/spatial/__init__.py +129 -0
  1169. scipy/spatial/_ckdtree.cp314t-win_arm64.lib +0 -0
  1170. scipy/spatial/_ckdtree.cp314t-win_arm64.pyd +0 -0
  1171. scipy/spatial/_distance_pybind.cp314t-win_arm64.lib +0 -0
  1172. scipy/spatial/_distance_pybind.cp314t-win_arm64.pyd +0 -0
  1173. scipy/spatial/_distance_wrap.cp314t-win_arm64.lib +0 -0
  1174. scipy/spatial/_distance_wrap.cp314t-win_arm64.pyd +0 -0
  1175. scipy/spatial/_geometric_slerp.py +238 -0
  1176. scipy/spatial/_hausdorff.cp314t-win_arm64.lib +0 -0
  1177. scipy/spatial/_hausdorff.cp314t-win_arm64.pyd +0 -0
  1178. scipy/spatial/_kdtree.py +920 -0
  1179. scipy/spatial/_plotutils.py +274 -0
  1180. scipy/spatial/_procrustes.py +132 -0
  1181. scipy/spatial/_qhull.cp314t-win_arm64.lib +0 -0
  1182. scipy/spatial/_qhull.cp314t-win_arm64.pyd +0 -0
  1183. scipy/spatial/_qhull.pyi +213 -0
  1184. scipy/spatial/_spherical_voronoi.py +341 -0
  1185. scipy/spatial/_voronoi.cp314t-win_arm64.lib +0 -0
  1186. scipy/spatial/_voronoi.cp314t-win_arm64.pyd +0 -0
  1187. scipy/spatial/_voronoi.pyi +4 -0
  1188. scipy/spatial/ckdtree.py +18 -0
  1189. scipy/spatial/distance.py +3147 -0
  1190. scipy/spatial/distance.pyi +210 -0
  1191. scipy/spatial/kdtree.py +25 -0
  1192. scipy/spatial/qhull.py +25 -0
  1193. scipy/spatial/qhull_src/COPYING_QHULL.txt +39 -0
  1194. scipy/spatial/tests/__init__.py +0 -0
  1195. scipy/spatial/tests/data/cdist-X1.txt +10 -0
  1196. scipy/spatial/tests/data/cdist-X2.txt +20 -0
  1197. scipy/spatial/tests/data/degenerate_pointset.npz +0 -0
  1198. scipy/spatial/tests/data/iris.txt +150 -0
  1199. scipy/spatial/tests/data/pdist-boolean-inp.txt +20 -0
  1200. scipy/spatial/tests/data/pdist-chebyshev-ml-iris.txt +1 -0
  1201. scipy/spatial/tests/data/pdist-chebyshev-ml.txt +1 -0
  1202. scipy/spatial/tests/data/pdist-cityblock-ml-iris.txt +1 -0
  1203. scipy/spatial/tests/data/pdist-cityblock-ml.txt +1 -0
  1204. scipy/spatial/tests/data/pdist-correlation-ml-iris.txt +1 -0
  1205. scipy/spatial/tests/data/pdist-correlation-ml.txt +1 -0
  1206. scipy/spatial/tests/data/pdist-cosine-ml-iris.txt +1 -0
  1207. scipy/spatial/tests/data/pdist-cosine-ml.txt +1 -0
  1208. scipy/spatial/tests/data/pdist-double-inp.txt +20 -0
  1209. scipy/spatial/tests/data/pdist-euclidean-ml-iris.txt +1 -0
  1210. scipy/spatial/tests/data/pdist-euclidean-ml.txt +1 -0
  1211. scipy/spatial/tests/data/pdist-hamming-ml.txt +1 -0
  1212. scipy/spatial/tests/data/pdist-jaccard-ml.txt +1 -0
  1213. scipy/spatial/tests/data/pdist-jensenshannon-ml-iris.txt +1 -0
  1214. scipy/spatial/tests/data/pdist-jensenshannon-ml.txt +1 -0
  1215. scipy/spatial/tests/data/pdist-minkowski-3.2-ml-iris.txt +1 -0
  1216. scipy/spatial/tests/data/pdist-minkowski-3.2-ml.txt +1 -0
  1217. scipy/spatial/tests/data/pdist-minkowski-5.8-ml-iris.txt +1 -0
  1218. scipy/spatial/tests/data/pdist-seuclidean-ml-iris.txt +1 -0
  1219. scipy/spatial/tests/data/pdist-seuclidean-ml.txt +1 -0
  1220. scipy/spatial/tests/data/pdist-spearman-ml.txt +1 -0
  1221. scipy/spatial/tests/data/random-bool-data.txt +100 -0
  1222. scipy/spatial/tests/data/random-double-data.txt +100 -0
  1223. scipy/spatial/tests/data/random-int-data.txt +100 -0
  1224. scipy/spatial/tests/data/random-uint-data.txt +100 -0
  1225. scipy/spatial/tests/data/selfdual-4d-polytope.txt +27 -0
  1226. scipy/spatial/tests/test__plotutils.py +91 -0
  1227. scipy/spatial/tests/test__procrustes.py +116 -0
  1228. scipy/spatial/tests/test_distance.py +2389 -0
  1229. scipy/spatial/tests/test_hausdorff.py +199 -0
  1230. scipy/spatial/tests/test_kdtree.py +1536 -0
  1231. scipy/spatial/tests/test_qhull.py +1313 -0
  1232. scipy/spatial/tests/test_slerp.py +417 -0
  1233. scipy/spatial/tests/test_spherical_voronoi.py +358 -0
  1234. scipy/spatial/transform/__init__.py +31 -0
  1235. scipy/spatial/transform/_rigid_transform.cp314t-win_arm64.lib +0 -0
  1236. scipy/spatial/transform/_rigid_transform.cp314t-win_arm64.pyd +0 -0
  1237. scipy/spatial/transform/_rotation.cp314t-win_arm64.lib +0 -0
  1238. scipy/spatial/transform/_rotation.cp314t-win_arm64.pyd +0 -0
  1239. scipy/spatial/transform/_rotation_groups.py +140 -0
  1240. scipy/spatial/transform/_rotation_spline.py +460 -0
  1241. scipy/spatial/transform/rotation.py +21 -0
  1242. scipy/spatial/transform/tests/__init__.py +0 -0
  1243. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  1244. scipy/spatial/transform/tests/test_rotation.py +2569 -0
  1245. scipy/spatial/transform/tests/test_rotation_groups.py +169 -0
  1246. scipy/spatial/transform/tests/test_rotation_spline.py +183 -0
  1247. scipy/special/__init__.pxd +1 -0
  1248. scipy/special/__init__.py +841 -0
  1249. scipy/special/_add_newdocs.py +9961 -0
  1250. scipy/special/_basic.py +3576 -0
  1251. scipy/special/_comb.cp314t-win_arm64.lib +0 -0
  1252. scipy/special/_comb.cp314t-win_arm64.pyd +0 -0
  1253. scipy/special/_ellip_harm.py +214 -0
  1254. scipy/special/_ellip_harm_2.cp314t-win_arm64.lib +0 -0
  1255. scipy/special/_ellip_harm_2.cp314t-win_arm64.pyd +0 -0
  1256. scipy/special/_gufuncs.cp314t-win_arm64.lib +0 -0
  1257. scipy/special/_gufuncs.cp314t-win_arm64.pyd +0 -0
  1258. scipy/special/_input_validation.py +17 -0
  1259. scipy/special/_lambertw.py +149 -0
  1260. scipy/special/_logsumexp.py +426 -0
  1261. scipy/special/_mptestutils.py +453 -0
  1262. scipy/special/_multiufuncs.py +610 -0
  1263. scipy/special/_orthogonal.py +2592 -0
  1264. scipy/special/_orthogonal.pyi +330 -0
  1265. scipy/special/_precompute/__init__.py +0 -0
  1266. scipy/special/_precompute/cosine_cdf.py +17 -0
  1267. scipy/special/_precompute/expn_asy.py +54 -0
  1268. scipy/special/_precompute/gammainc_asy.py +116 -0
  1269. scipy/special/_precompute/gammainc_data.py +124 -0
  1270. scipy/special/_precompute/hyp2f1_data.py +484 -0
  1271. scipy/special/_precompute/lambertw.py +68 -0
  1272. scipy/special/_precompute/loggamma.py +43 -0
  1273. scipy/special/_precompute/struve_convergence.py +131 -0
  1274. scipy/special/_precompute/utils.py +38 -0
  1275. scipy/special/_precompute/wright_bessel.py +342 -0
  1276. scipy/special/_precompute/wright_bessel_data.py +152 -0
  1277. scipy/special/_precompute/wrightomega.py +41 -0
  1278. scipy/special/_precompute/zetac.py +27 -0
  1279. scipy/special/_sf_error.py +15 -0
  1280. scipy/special/_specfun.cp314t-win_arm64.lib +0 -0
  1281. scipy/special/_specfun.cp314t-win_arm64.pyd +0 -0
  1282. scipy/special/_special_ufuncs.cp314t-win_arm64.lib +0 -0
  1283. scipy/special/_special_ufuncs.cp314t-win_arm64.pyd +0 -0
  1284. scipy/special/_spfun_stats.py +106 -0
  1285. scipy/special/_spherical_bessel.py +397 -0
  1286. scipy/special/_support_alternative_backends.py +295 -0
  1287. scipy/special/_test_internal.cp314t-win_arm64.lib +0 -0
  1288. scipy/special/_test_internal.cp314t-win_arm64.pyd +0 -0
  1289. scipy/special/_test_internal.pyi +9 -0
  1290. scipy/special/_testutils.py +321 -0
  1291. scipy/special/_ufuncs.cp314t-win_arm64.lib +0 -0
  1292. scipy/special/_ufuncs.cp314t-win_arm64.pyd +0 -0
  1293. scipy/special/_ufuncs.pyi +522 -0
  1294. scipy/special/_ufuncs.pyx +13173 -0
  1295. scipy/special/_ufuncs_cxx.cp314t-win_arm64.lib +0 -0
  1296. scipy/special/_ufuncs_cxx.cp314t-win_arm64.pyd +0 -0
  1297. scipy/special/_ufuncs_cxx.pxd +142 -0
  1298. scipy/special/_ufuncs_cxx.pyx +427 -0
  1299. scipy/special/_ufuncs_cxx_defs.h +147 -0
  1300. scipy/special/_ufuncs_defs.h +57 -0
  1301. scipy/special/add_newdocs.py +15 -0
  1302. scipy/special/basic.py +87 -0
  1303. scipy/special/cython_special.cp314t-win_arm64.lib +0 -0
  1304. scipy/special/cython_special.cp314t-win_arm64.pyd +0 -0
  1305. scipy/special/cython_special.pxd +259 -0
  1306. scipy/special/cython_special.pyi +3 -0
  1307. scipy/special/orthogonal.py +45 -0
  1308. scipy/special/sf_error.py +20 -0
  1309. scipy/special/specfun.py +24 -0
  1310. scipy/special/spfun_stats.py +17 -0
  1311. scipy/special/tests/__init__.py +0 -0
  1312. scipy/special/tests/_cython_examples/extending.pyx +12 -0
  1313. scipy/special/tests/_cython_examples/meson.build +34 -0
  1314. scipy/special/tests/data/__init__.py +0 -0
  1315. scipy/special/tests/data/boost.npz +0 -0
  1316. scipy/special/tests/data/gsl.npz +0 -0
  1317. scipy/special/tests/data/local.npz +0 -0
  1318. scipy/special/tests/test_basic.py +4815 -0
  1319. scipy/special/tests/test_bdtr.py +112 -0
  1320. scipy/special/tests/test_boost_ufuncs.py +64 -0
  1321. scipy/special/tests/test_boxcox.py +125 -0
  1322. scipy/special/tests/test_cdflib.py +712 -0
  1323. scipy/special/tests/test_cdft_asymptotic.py +49 -0
  1324. scipy/special/tests/test_cephes_intp_cast.py +29 -0
  1325. scipy/special/tests/test_cosine_distr.py +83 -0
  1326. scipy/special/tests/test_cython_special.py +363 -0
  1327. scipy/special/tests/test_data.py +719 -0
  1328. scipy/special/tests/test_dd.py +42 -0
  1329. scipy/special/tests/test_digamma.py +45 -0
  1330. scipy/special/tests/test_ellip_harm.py +278 -0
  1331. scipy/special/tests/test_erfinv.py +89 -0
  1332. scipy/special/tests/test_exponential_integrals.py +118 -0
  1333. scipy/special/tests/test_extending.py +28 -0
  1334. scipy/special/tests/test_faddeeva.py +85 -0
  1335. scipy/special/tests/test_gamma.py +12 -0
  1336. scipy/special/tests/test_gammainc.py +152 -0
  1337. scipy/special/tests/test_hyp2f1.py +2566 -0
  1338. scipy/special/tests/test_hypergeometric.py +234 -0
  1339. scipy/special/tests/test_iv_ratio.py +249 -0
  1340. scipy/special/tests/test_kolmogorov.py +491 -0
  1341. scipy/special/tests/test_lambertw.py +109 -0
  1342. scipy/special/tests/test_legendre.py +1518 -0
  1343. scipy/special/tests/test_log1mexp.py +85 -0
  1344. scipy/special/tests/test_loggamma.py +70 -0
  1345. scipy/special/tests/test_logit.py +162 -0
  1346. scipy/special/tests/test_logsumexp.py +469 -0
  1347. scipy/special/tests/test_mpmath.py +2293 -0
  1348. scipy/special/tests/test_nan_inputs.py +65 -0
  1349. scipy/special/tests/test_ndtr.py +77 -0
  1350. scipy/special/tests/test_ndtri_exp.py +94 -0
  1351. scipy/special/tests/test_orthogonal.py +821 -0
  1352. scipy/special/tests/test_orthogonal_eval.py +275 -0
  1353. scipy/special/tests/test_owens_t.py +53 -0
  1354. scipy/special/tests/test_pcf.py +24 -0
  1355. scipy/special/tests/test_pdtr.py +48 -0
  1356. scipy/special/tests/test_powm1.py +65 -0
  1357. scipy/special/tests/test_precompute_expn_asy.py +24 -0
  1358. scipy/special/tests/test_precompute_gammainc.py +108 -0
  1359. scipy/special/tests/test_precompute_utils.py +36 -0
  1360. scipy/special/tests/test_round.py +18 -0
  1361. scipy/special/tests/test_sf_error.py +146 -0
  1362. scipy/special/tests/test_sici.py +36 -0
  1363. scipy/special/tests/test_specfun.py +48 -0
  1364. scipy/special/tests/test_spence.py +32 -0
  1365. scipy/special/tests/test_spfun_stats.py +61 -0
  1366. scipy/special/tests/test_sph_harm.py +85 -0
  1367. scipy/special/tests/test_spherical_bessel.py +400 -0
  1368. scipy/special/tests/test_support_alternative_backends.py +248 -0
  1369. scipy/special/tests/test_trig.py +72 -0
  1370. scipy/special/tests/test_ufunc_signatures.py +46 -0
  1371. scipy/special/tests/test_wright_bessel.py +205 -0
  1372. scipy/special/tests/test_wrightomega.py +117 -0
  1373. scipy/special/tests/test_zeta.py +301 -0
  1374. scipy/stats/__init__.py +670 -0
  1375. scipy/stats/_ansari_swilk_statistics.cp314t-win_arm64.lib +0 -0
  1376. scipy/stats/_ansari_swilk_statistics.cp314t-win_arm64.pyd +0 -0
  1377. scipy/stats/_axis_nan_policy.py +692 -0
  1378. scipy/stats/_biasedurn.cp314t-win_arm64.lib +0 -0
  1379. scipy/stats/_biasedurn.cp314t-win_arm64.pyd +0 -0
  1380. scipy/stats/_biasedurn.pxd +27 -0
  1381. scipy/stats/_binned_statistic.py +795 -0
  1382. scipy/stats/_binomtest.py +375 -0
  1383. scipy/stats/_bws_test.py +177 -0
  1384. scipy/stats/_censored_data.py +459 -0
  1385. scipy/stats/_common.py +5 -0
  1386. scipy/stats/_constants.py +42 -0
  1387. scipy/stats/_continued_fraction.py +387 -0
  1388. scipy/stats/_continuous_distns.py +12486 -0
  1389. scipy/stats/_correlation.py +210 -0
  1390. scipy/stats/_covariance.py +636 -0
  1391. scipy/stats/_crosstab.py +204 -0
  1392. scipy/stats/_discrete_distns.py +2098 -0
  1393. scipy/stats/_distn_infrastructure.py +4201 -0
  1394. scipy/stats/_distr_params.py +299 -0
  1395. scipy/stats/_distribution_infrastructure.py +5750 -0
  1396. scipy/stats/_entropy.py +428 -0
  1397. scipy/stats/_finite_differences.py +145 -0
  1398. scipy/stats/_fit.py +1351 -0
  1399. scipy/stats/_hypotests.py +2060 -0
  1400. scipy/stats/_kde.py +732 -0
  1401. scipy/stats/_ksstats.py +600 -0
  1402. scipy/stats/_levy_stable/__init__.py +1231 -0
  1403. scipy/stats/_levy_stable/levyst.cp314t-win_arm64.lib +0 -0
  1404. scipy/stats/_levy_stable/levyst.cp314t-win_arm64.pyd +0 -0
  1405. scipy/stats/_mannwhitneyu.py +492 -0
  1406. scipy/stats/_mgc.py +550 -0
  1407. scipy/stats/_morestats.py +4626 -0
  1408. scipy/stats/_mstats_basic.py +3658 -0
  1409. scipy/stats/_mstats_extras.py +521 -0
  1410. scipy/stats/_multicomp.py +449 -0
  1411. scipy/stats/_multivariate.py +7281 -0
  1412. scipy/stats/_new_distributions.py +452 -0
  1413. scipy/stats/_odds_ratio.py +466 -0
  1414. scipy/stats/_page_trend_test.py +486 -0
  1415. scipy/stats/_probability_distribution.py +1964 -0
  1416. scipy/stats/_qmc.py +2956 -0
  1417. scipy/stats/_qmc_cy.cp314t-win_arm64.lib +0 -0
  1418. scipy/stats/_qmc_cy.cp314t-win_arm64.pyd +0 -0
  1419. scipy/stats/_qmc_cy.pyi +54 -0
  1420. scipy/stats/_qmvnt.py +454 -0
  1421. scipy/stats/_qmvnt_cy.cp314t-win_arm64.lib +0 -0
  1422. scipy/stats/_qmvnt_cy.cp314t-win_arm64.pyd +0 -0
  1423. scipy/stats/_quantile.py +335 -0
  1424. scipy/stats/_rcont/__init__.py +4 -0
  1425. scipy/stats/_rcont/rcont.cp314t-win_arm64.lib +0 -0
  1426. scipy/stats/_rcont/rcont.cp314t-win_arm64.pyd +0 -0
  1427. scipy/stats/_relative_risk.py +263 -0
  1428. scipy/stats/_resampling.py +2352 -0
  1429. scipy/stats/_result_classes.py +40 -0
  1430. scipy/stats/_sampling.py +1314 -0
  1431. scipy/stats/_sensitivity_analysis.py +713 -0
  1432. scipy/stats/_sobol.cp314t-win_arm64.lib +0 -0
  1433. scipy/stats/_sobol.cp314t-win_arm64.pyd +0 -0
  1434. scipy/stats/_sobol.pyi +54 -0
  1435. scipy/stats/_sobol_direction_numbers.npz +0 -0
  1436. scipy/stats/_stats.cp314t-win_arm64.lib +0 -0
  1437. scipy/stats/_stats.cp314t-win_arm64.pyd +0 -0
  1438. scipy/stats/_stats.pxd +10 -0
  1439. scipy/stats/_stats_mstats_common.py +322 -0
  1440. scipy/stats/_stats_py.py +11089 -0
  1441. scipy/stats/_stats_pythran.cp314t-win_arm64.lib +0 -0
  1442. scipy/stats/_stats_pythran.cp314t-win_arm64.pyd +0 -0
  1443. scipy/stats/_survival.py +683 -0
  1444. scipy/stats/_tukeylambda_stats.py +199 -0
  1445. scipy/stats/_unuran/__init__.py +0 -0
  1446. scipy/stats/_unuran/unuran_wrapper.cp314t-win_arm64.lib +0 -0
  1447. scipy/stats/_unuran/unuran_wrapper.cp314t-win_arm64.pyd +0 -0
  1448. scipy/stats/_unuran/unuran_wrapper.pyi +179 -0
  1449. scipy/stats/_variation.py +126 -0
  1450. scipy/stats/_warnings_errors.py +38 -0
  1451. scipy/stats/_wilcoxon.py +265 -0
  1452. scipy/stats/biasedurn.py +16 -0
  1453. scipy/stats/contingency.py +521 -0
  1454. scipy/stats/distributions.py +24 -0
  1455. scipy/stats/kde.py +18 -0
  1456. scipy/stats/morestats.py +27 -0
  1457. scipy/stats/mstats.py +140 -0
  1458. scipy/stats/mstats_basic.py +42 -0
  1459. scipy/stats/mstats_extras.py +25 -0
  1460. scipy/stats/mvn.py +17 -0
  1461. scipy/stats/qmc.py +236 -0
  1462. scipy/stats/sampling.py +73 -0
  1463. scipy/stats/stats.py +41 -0
  1464. scipy/stats/tests/__init__.py +0 -0
  1465. scipy/stats/tests/common_tests.py +356 -0
  1466. scipy/stats/tests/data/_mvt.py +171 -0
  1467. scipy/stats/tests/data/fisher_exact_results_from_r.py +607 -0
  1468. scipy/stats/tests/data/jf_skew_t_gamlss_pdf_data.npy +0 -0
  1469. scipy/stats/tests/data/levy_stable/stable-Z1-cdf-sample-data.npy +0 -0
  1470. scipy/stats/tests/data/levy_stable/stable-Z1-pdf-sample-data.npy +0 -0
  1471. scipy/stats/tests/data/levy_stable/stable-loc-scale-sample-data.npy +0 -0
  1472. scipy/stats/tests/data/nist_anova/AtmWtAg.dat +108 -0
  1473. scipy/stats/tests/data/nist_anova/SiRstv.dat +85 -0
  1474. scipy/stats/tests/data/nist_anova/SmLs01.dat +249 -0
  1475. scipy/stats/tests/data/nist_anova/SmLs02.dat +1869 -0
  1476. scipy/stats/tests/data/nist_anova/SmLs03.dat +18069 -0
  1477. scipy/stats/tests/data/nist_anova/SmLs04.dat +249 -0
  1478. scipy/stats/tests/data/nist_anova/SmLs05.dat +1869 -0
  1479. scipy/stats/tests/data/nist_anova/SmLs06.dat +18069 -0
  1480. scipy/stats/tests/data/nist_anova/SmLs07.dat +249 -0
  1481. scipy/stats/tests/data/nist_anova/SmLs08.dat +1869 -0
  1482. scipy/stats/tests/data/nist_anova/SmLs09.dat +18069 -0
  1483. scipy/stats/tests/data/nist_linregress/Norris.dat +97 -0
  1484. scipy/stats/tests/data/rel_breitwigner_pdf_sample_data_ROOT.npy +0 -0
  1485. scipy/stats/tests/data/studentized_range_mpmath_ref.json +1499 -0
  1486. scipy/stats/tests/test_axis_nan_policy.py +1388 -0
  1487. scipy/stats/tests/test_binned_statistic.py +568 -0
  1488. scipy/stats/tests/test_censored_data.py +152 -0
  1489. scipy/stats/tests/test_contingency.py +294 -0
  1490. scipy/stats/tests/test_continued_fraction.py +173 -0
  1491. scipy/stats/tests/test_continuous.py +2198 -0
  1492. scipy/stats/tests/test_continuous_basic.py +1053 -0
  1493. scipy/stats/tests/test_continuous_fit_censored.py +683 -0
  1494. scipy/stats/tests/test_correlation.py +80 -0
  1495. scipy/stats/tests/test_crosstab.py +115 -0
  1496. scipy/stats/tests/test_discrete_basic.py +580 -0
  1497. scipy/stats/tests/test_discrete_distns.py +700 -0
  1498. scipy/stats/tests/test_distributions.py +10413 -0
  1499. scipy/stats/tests/test_entropy.py +322 -0
  1500. scipy/stats/tests/test_fast_gen_inversion.py +435 -0
  1501. scipy/stats/tests/test_fit.py +1090 -0
  1502. scipy/stats/tests/test_hypotests.py +1991 -0
  1503. scipy/stats/tests/test_kdeoth.py +676 -0
  1504. scipy/stats/tests/test_marray.py +289 -0
  1505. scipy/stats/tests/test_mgc.py +217 -0
  1506. scipy/stats/tests/test_morestats.py +3259 -0
  1507. scipy/stats/tests/test_mstats_basic.py +2071 -0
  1508. scipy/stats/tests/test_mstats_extras.py +172 -0
  1509. scipy/stats/tests/test_multicomp.py +405 -0
  1510. scipy/stats/tests/test_multivariate.py +4381 -0
  1511. scipy/stats/tests/test_odds_ratio.py +148 -0
  1512. scipy/stats/tests/test_qmc.py +1492 -0
  1513. scipy/stats/tests/test_quantile.py +199 -0
  1514. scipy/stats/tests/test_rank.py +345 -0
  1515. scipy/stats/tests/test_relative_risk.py +95 -0
  1516. scipy/stats/tests/test_resampling.py +2000 -0
  1517. scipy/stats/tests/test_sampling.py +1450 -0
  1518. scipy/stats/tests/test_sensitivity_analysis.py +310 -0
  1519. scipy/stats/tests/test_stats.py +9707 -0
  1520. scipy/stats/tests/test_survival.py +466 -0
  1521. scipy/stats/tests/test_tukeylambda_stats.py +85 -0
  1522. scipy/stats/tests/test_variation.py +216 -0
  1523. scipy/version.py +12 -0
  1524. scipy-1.16.2.dist-info/DELVEWHEEL +2 -0
  1525. scipy-1.16.2.dist-info/LICENSE.txt +912 -0
  1526. scipy-1.16.2.dist-info/METADATA +1061 -0
  1527. scipy-1.16.2.dist-info/RECORD +1530 -0
  1528. scipy-1.16.2.dist-info/WHEEL +4 -0
  1529. scipy.libs/msvcp140-5f1c5dd31916990d94181e07bc3afb32.dll +0 -0
  1530. scipy.libs/scipy_openblas-f3ac85b1f412f7e86514c923dc4058d1.dll +0 -0
@@ -0,0 +1,4201 @@
1
+ #
2
+ # Author: Travis Oliphant 2002-2011 with contributions from
3
+ # SciPy Developers 2004-2011
4
+ #
5
+ from scipy._lib._util import getfullargspec_no_self as _getfullargspec
6
+
7
+ import sys
8
+ import keyword
9
+ import re
10
+ import types
11
+ import warnings
12
+ from itertools import zip_longest
13
+
14
+ from scipy._lib import doccer
15
+ from ._distr_params import distcont, distdiscrete
16
+ from scipy._lib._util import check_random_state
17
+ import scipy._lib.array_api_extra as xpx
18
+
19
+ from scipy.special import comb, entr
20
+
21
+
22
+ # for root finding for continuous distribution ppf, and maximum likelihood
23
+ # estimation
24
+ from scipy import optimize
25
+
26
+ # for functions of continuous distributions (e.g. moments, entropy, cdf)
27
+ from scipy import integrate
28
+
29
+ # to approximate the pdf of a continuous distribution given its cdf
30
+ from scipy.stats._finite_differences import _derivative
31
+
32
+ # for scipy.stats.entropy. Attempts to import just that function or file
33
+ # have cause import problems
34
+ from scipy import stats
35
+
36
+ from numpy import (arange, putmask, ones, shape, ndarray, zeros, floor,
37
+ logical_and, log, sqrt, place, argmax, vectorize, asarray,
38
+ nan, inf, isinf, empty)
39
+
40
+ import numpy as np
41
+ from ._constants import _XMAX, _LOGXMAX
42
+ from ._censored_data import CensoredData
43
+ from scipy.stats._warnings_errors import FitError
44
+
45
+ # These are the docstring parts used for substitution in specific
46
+ # distribution docstrings
47
+
48
+ docheaders = {'methods': """\nMethods\n-------\n""",
49
+ 'notes': """\nNotes\n-----\n""",
50
+ 'examples': """\nExamples\n--------\n"""}
51
+
52
+ _doc_rvs = """\
53
+ rvs(%(shapes)s, loc=0, scale=1, size=1, random_state=None)
54
+ Random variates.
55
+ """
56
+ _doc_pdf = """\
57
+ pdf(x, %(shapes)s, loc=0, scale=1)
58
+ Probability density function.
59
+ """
60
+ _doc_logpdf = """\
61
+ logpdf(x, %(shapes)s, loc=0, scale=1)
62
+ Log of the probability density function.
63
+ """
64
+ _doc_pmf = """\
65
+ pmf(k, %(shapes)s, loc=0, scale=1)
66
+ Probability mass function.
67
+ """
68
+ _doc_logpmf = """\
69
+ logpmf(k, %(shapes)s, loc=0, scale=1)
70
+ Log of the probability mass function.
71
+ """
72
+ _doc_cdf = """\
73
+ cdf(x, %(shapes)s, loc=0, scale=1)
74
+ Cumulative distribution function.
75
+ """
76
+ _doc_logcdf = """\
77
+ logcdf(x, %(shapes)s, loc=0, scale=1)
78
+ Log of the cumulative distribution function.
79
+ """
80
+ _doc_sf = """\
81
+ sf(x, %(shapes)s, loc=0, scale=1)
82
+ Survival function (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
83
+ """ # noqa: E501
84
+ _doc_logsf = """\
85
+ logsf(x, %(shapes)s, loc=0, scale=1)
86
+ Log of the survival function.
87
+ """
88
+ _doc_ppf = """\
89
+ ppf(q, %(shapes)s, loc=0, scale=1)
90
+ Percent point function (inverse of ``cdf`` --- percentiles).
91
+ """
92
+ _doc_isf = """\
93
+ isf(q, %(shapes)s, loc=0, scale=1)
94
+ Inverse survival function (inverse of ``sf``).
95
+ """
96
+ _doc_moment = """\
97
+ moment(order, %(shapes)s, loc=0, scale=1)
98
+ Non-central moment of the specified order.
99
+ """
100
+ _doc_stats = """\
101
+ stats(%(shapes)s, loc=0, scale=1, moments='mv')
102
+ Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
103
+ """
104
+ _doc_entropy = """\
105
+ entropy(%(shapes)s, loc=0, scale=1)
106
+ (Differential) entropy of the RV.
107
+ """
108
+ _doc_fit = """\
109
+ fit(data)
110
+ Parameter estimates for generic data.
111
+ See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
112
+ keyword arguments.
113
+ """ # noqa: E501
114
+ _doc_expect = """\
115
+ expect(func, args=(%(shapes_)s), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
116
+ Expected value of a function (of one argument) with respect to the distribution.
117
+ """ # noqa: E501
118
+ _doc_expect_discrete = """\
119
+ expect(func, args=(%(shapes_)s), loc=0, lb=None, ub=None, conditional=False)
120
+ Expected value of a function (of one argument) with respect to the distribution.
121
+ """
122
+ _doc_median = """\
123
+ median(%(shapes)s, loc=0, scale=1)
124
+ Median of the distribution.
125
+ """
126
+ _doc_mean = """\
127
+ mean(%(shapes)s, loc=0, scale=1)
128
+ Mean of the distribution.
129
+ """
130
+ _doc_var = """\
131
+ var(%(shapes)s, loc=0, scale=1)
132
+ Variance of the distribution.
133
+ """
134
+ _doc_std = """\
135
+ std(%(shapes)s, loc=0, scale=1)
136
+ Standard deviation of the distribution.
137
+ """
138
+ _doc_interval = """\
139
+ interval(confidence, %(shapes)s, loc=0, scale=1)
140
+ Confidence interval with equal areas around the median.
141
+ """
142
+ _doc_allmethods = ''.join([docheaders['methods'], _doc_rvs, _doc_pdf,
143
+ _doc_logpdf, _doc_cdf, _doc_logcdf, _doc_sf,
144
+ _doc_logsf, _doc_ppf, _doc_isf, _doc_moment,
145
+ _doc_stats, _doc_entropy, _doc_fit,
146
+ _doc_expect, _doc_median,
147
+ _doc_mean, _doc_var, _doc_std, _doc_interval])
148
+
149
+ _doc_default_longsummary = """\
150
+ As an instance of the `rv_continuous` class, `%(name)s` object inherits from it
151
+ a collection of generic methods (see below for the full list),
152
+ and completes them with details specific for this particular distribution.
153
+ """
154
+
155
+ _doc_default_frozen_note = """
156
+ Alternatively, the object may be called (as a function) to fix the shape,
157
+ location, and scale parameters returning a "frozen" continuous RV object:
158
+
159
+ rv = %(name)s(%(shapes)s, loc=0, scale=1)
160
+ - Frozen RV object with the same methods but holding the given shape,
161
+ location, and scale fixed.
162
+ """
163
+ _doc_default_example = """\
164
+ Examples
165
+ --------
166
+ >>> import numpy as np
167
+ >>> from scipy.stats import %(name)s
168
+ >>> import matplotlib.pyplot as plt
169
+ >>> fig, ax = plt.subplots(1, 1)
170
+
171
+ Get the support:
172
+
173
+ %(set_vals_stmt)s
174
+ >>> lb, ub = %(name)s.support(%(shapes)s)
175
+
176
+ Calculate the first four moments:
177
+
178
+ >>> mean, var, skew, kurt = %(name)s.stats(%(shapes)s, moments='mvsk')
179
+
180
+ Display the probability density function (``pdf``):
181
+
182
+ >>> x = np.linspace(%(name)s.ppf(0.01, %(shapes)s),
183
+ ... %(name)s.ppf(0.99, %(shapes)s), 100)
184
+ >>> ax.plot(x, %(name)s.pdf(x, %(shapes)s),
185
+ ... 'r-', lw=5, alpha=0.6, label='%(name)s pdf')
186
+
187
+ Alternatively, the distribution object can be called (as a function)
188
+ to fix the shape, location and scale parameters. This returns a "frozen"
189
+ RV object holding the given parameters fixed.
190
+
191
+ Freeze the distribution and display the frozen ``pdf``:
192
+
193
+ >>> rv = %(name)s(%(shapes)s)
194
+ >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')
195
+
196
+ Check accuracy of ``cdf`` and ``ppf``:
197
+
198
+ >>> vals = %(name)s.ppf([0.001, 0.5, 0.999], %(shapes)s)
199
+ >>> np.allclose([0.001, 0.5, 0.999], %(name)s.cdf(vals, %(shapes)s))
200
+ True
201
+
202
+ Generate random numbers:
203
+
204
+ >>> r = %(name)s.rvs(%(shapes)s, size=1000)
205
+
206
+ And compare the histogram:
207
+
208
+ >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
209
+ >>> ax.set_xlim([x[0], x[-1]])
210
+ >>> ax.legend(loc='best', frameon=False)
211
+ >>> plt.show()
212
+
213
+ """
214
+
215
+ _doc_default_locscale = """\
216
+ The probability density above is defined in the "standardized" form. To shift
217
+ and/or scale the distribution use the ``loc`` and ``scale`` parameters.
218
+ Specifically, ``%(name)s.pdf(x, %(shapes)s, loc, scale)`` is identically
219
+ equivalent to ``%(name)s.pdf(y, %(shapes)s) / scale`` with
220
+ ``y = (x - loc) / scale``. Note that shifting the location of a distribution
221
+ does not make it a "noncentral" distribution; noncentral generalizations of
222
+ some distributions are available in separate classes.
223
+ """
224
+
225
+ _doc_default = ''.join([_doc_default_longsummary,
226
+ _doc_allmethods,
227
+ '\n',
228
+ _doc_default_example])
229
+
230
+ _doc_default_before_notes = ''.join([_doc_default_longsummary,
231
+ _doc_allmethods])
232
+
233
+ docdict = {
234
+ 'rvs': _doc_rvs,
235
+ 'pdf': _doc_pdf,
236
+ 'logpdf': _doc_logpdf,
237
+ 'cdf': _doc_cdf,
238
+ 'logcdf': _doc_logcdf,
239
+ 'sf': _doc_sf,
240
+ 'logsf': _doc_logsf,
241
+ 'ppf': _doc_ppf,
242
+ 'isf': _doc_isf,
243
+ 'stats': _doc_stats,
244
+ 'entropy': _doc_entropy,
245
+ 'fit': _doc_fit,
246
+ 'moment': _doc_moment,
247
+ 'expect': _doc_expect,
248
+ 'interval': _doc_interval,
249
+ 'mean': _doc_mean,
250
+ 'std': _doc_std,
251
+ 'var': _doc_var,
252
+ 'median': _doc_median,
253
+ 'allmethods': _doc_allmethods,
254
+ 'longsummary': _doc_default_longsummary,
255
+ 'frozennote': _doc_default_frozen_note,
256
+ 'example': _doc_default_example,
257
+ 'default': _doc_default,
258
+ 'before_notes': _doc_default_before_notes,
259
+ 'after_notes': _doc_default_locscale
260
+ }
261
+
262
+ # Reuse common content between continuous and discrete docs, change some
263
+ # minor bits.
264
+ docdict_discrete = docdict.copy()
265
+
266
+ docdict_discrete['pmf'] = _doc_pmf
267
+ docdict_discrete['logpmf'] = _doc_logpmf
268
+ docdict_discrete['expect'] = _doc_expect_discrete
269
+ _doc_disc_methods = ['rvs', 'pmf', 'logpmf', 'cdf', 'logcdf', 'sf', 'logsf',
270
+ 'ppf', 'isf', 'stats', 'entropy', 'expect', 'median',
271
+ 'mean', 'var', 'std', 'interval']
272
+ for obj in _doc_disc_methods:
273
+ docdict_discrete[obj] = docdict_discrete[obj].replace(', scale=1', '')
274
+
275
+ _doc_disc_methods_err_varname = ['cdf', 'logcdf', 'sf', 'logsf']
276
+ for obj in _doc_disc_methods_err_varname:
277
+ docdict_discrete[obj] = docdict_discrete[obj].replace('(x, ', '(k, ')
278
+
279
+ docdict_discrete.pop('pdf')
280
+ docdict_discrete.pop('logpdf')
281
+
282
+ _doc_allmethods = ''.join([docdict_discrete[obj] for obj in _doc_disc_methods])
283
+ docdict_discrete['allmethods'] = docheaders['methods'] + _doc_allmethods
284
+
285
+ docdict_discrete['longsummary'] = _doc_default_longsummary.replace(
286
+ 'rv_continuous', 'rv_discrete')
287
+
288
+ _doc_default_frozen_note = """
289
+ Alternatively, the object may be called (as a function) to fix the shape and
290
+ location parameters returning a "frozen" discrete RV object:
291
+
292
+ rv = %(name)s(%(shapes)s, loc=0)
293
+ - Frozen RV object with the same methods but holding the given shape and
294
+ location fixed.
295
+ """
296
+ docdict_discrete['frozennote'] = _doc_default_frozen_note
297
+
298
+ _doc_default_discrete_example = """\
299
+ Examples
300
+ --------
301
+ >>> import numpy as np
302
+ >>> from scipy.stats import %(name)s
303
+ >>> import matplotlib.pyplot as plt
304
+ >>> fig, ax = plt.subplots(1, 1)
305
+
306
+ Get the support:
307
+
308
+ %(set_vals_stmt)s
309
+ >>> lb, ub = %(name)s.support(%(shapes)s)
310
+
311
+ Calculate the first four moments:
312
+
313
+ >>> mean, var, skew, kurt = %(name)s.stats(%(shapes)s, moments='mvsk')
314
+
315
+ Display the probability mass function (``pmf``):
316
+
317
+ >>> x = np.arange(%(name)s.ppf(0.01, %(shapes)s),
318
+ ... %(name)s.ppf(0.99, %(shapes)s))
319
+ >>> ax.plot(x, %(name)s.pmf(x, %(shapes)s), 'bo', ms=8, label='%(name)s pmf')
320
+ >>> ax.vlines(x, 0, %(name)s.pmf(x, %(shapes)s), colors='b', lw=5, alpha=0.5)
321
+
322
+ Alternatively, the distribution object can be called (as a function)
323
+ to fix the shape and location. This returns a "frozen" RV object holding
324
+ the given parameters fixed.
325
+
326
+ Freeze the distribution and display the frozen ``pmf``:
327
+
328
+ >>> rv = %(name)s(%(shapes)s)
329
+ >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
330
+ ... label='frozen pmf')
331
+ >>> ax.legend(loc='best', frameon=False)
332
+ >>> plt.show()
333
+
334
+ Check accuracy of ``cdf`` and ``ppf``:
335
+
336
+ >>> prob = %(name)s.cdf(x, %(shapes)s)
337
+ >>> np.allclose(x, %(name)s.ppf(prob, %(shapes)s))
338
+ True
339
+
340
+ Generate random numbers:
341
+
342
+ >>> r = %(name)s.rvs(%(shapes)s, size=1000)
343
+ """
344
+
345
+
346
+ _doc_default_discrete_locscale = """\
347
+ The probability mass function above is defined in the "standardized" form.
348
+ To shift distribution use the ``loc`` parameter.
349
+ Specifically, ``%(name)s.pmf(k, %(shapes)s, loc)`` is identically
350
+ equivalent to ``%(name)s.pmf(k - loc, %(shapes)s)``.
351
+ """
352
+
353
+ docdict_discrete['example'] = _doc_default_discrete_example
354
+ docdict_discrete['after_notes'] = _doc_default_discrete_locscale
355
+
356
+ _doc_default_before_notes = ''.join([docdict_discrete['longsummary'],
357
+ docdict_discrete['allmethods']])
358
+ docdict_discrete['before_notes'] = _doc_default_before_notes
359
+
360
+ _doc_default_disc = ''.join([docdict_discrete['longsummary'],
361
+ docdict_discrete['allmethods'],
362
+ docdict_discrete['frozennote'],
363
+ docdict_discrete['example']])
364
+ docdict_discrete['default'] = _doc_default_disc
365
+
366
+ # clean up all the separate docstring elements, we do not need them anymore
367
+ for obj in [s for s in dir() if s.startswith('_doc_')]:
368
+ exec('del ' + obj)
369
+ del obj
370
+
371
+
372
+ def _moment(data, n, mu=None):
373
+ if mu is None:
374
+ mu = data.mean()
375
+ return ((data - mu)**n).mean()
376
+
377
+
378
+ def _moment_from_stats(n, mu, mu2, g1, g2, moment_func, args):
379
+ if (n == 0):
380
+ return 1.0
381
+ elif (n == 1):
382
+ if mu is None:
383
+ val = moment_func(1, *args)
384
+ else:
385
+ val = mu
386
+ elif (n == 2):
387
+ if mu2 is None or mu is None:
388
+ val = moment_func(2, *args)
389
+ else:
390
+ val = mu2 + mu*mu
391
+ elif (n == 3):
392
+ if g1 is None or mu2 is None or mu is None:
393
+ val = moment_func(3, *args)
394
+ else:
395
+ mu3 = g1 * np.power(mu2, 1.5) # 3rd central moment
396
+ val = mu3+3*mu*mu2+mu*mu*mu # 3rd non-central moment
397
+ elif (n == 4):
398
+ if g1 is None or g2 is None or mu2 is None or mu is None:
399
+ val = moment_func(4, *args)
400
+ else:
401
+ mu4 = (g2+3.0)*(mu2**2.0) # 4th central moment
402
+ mu3 = g1*np.power(mu2, 1.5) # 3rd central moment
403
+ val = mu4+4*mu*mu3+6*mu*mu*mu2+mu*mu*mu*mu
404
+ else:
405
+ val = moment_func(n, *args)
406
+
407
+ return val
408
+
409
+
410
+ def _skew(data):
411
+ """
412
+ skew is third central moment / variance**(1.5)
413
+ """
414
+ data = np.ravel(data)
415
+ mu = data.mean()
416
+ m2 = ((data - mu)**2).mean()
417
+ m3 = ((data - mu)**3).mean()
418
+ return m3 / np.power(m2, 1.5)
419
+
420
+
421
+ def _kurtosis(data):
422
+ """Fisher's excess kurtosis is fourth central moment / variance**2 - 3."""
423
+ data = np.ravel(data)
424
+ mu = data.mean()
425
+ m2 = ((data - mu)**2).mean()
426
+ m4 = ((data - mu)**4).mean()
427
+ return m4 / m2**2 - 3
428
+
429
+ def _vectorize_rvs_over_shapes(_rvs1):
430
+ """Decorator that vectorizes _rvs method to work on ndarray shapes"""
431
+ # _rvs1 must be a _function_ that accepts _scalar_ args as positional
432
+ # arguments, `size` and `random_state` as keyword arguments.
433
+ # _rvs1 must return a random variate array with shape `size`. If `size` is
434
+ # None, _rvs1 must return a scalar.
435
+ # When applied to _rvs1, this decorator broadcasts ndarray args
436
+ # and loops over them, calling _rvs1 for each set of scalar args.
437
+ # For usage example, see _nchypergeom_gen
438
+ def _rvs(*args, size, random_state):
439
+ _rvs1_size, _rvs1_indices = _check_shape(args[0].shape, size)
440
+
441
+ size = np.array(size)
442
+ _rvs1_size = np.array(_rvs1_size)
443
+ _rvs1_indices = np.array(_rvs1_indices)
444
+
445
+ if np.all(_rvs1_indices): # all args are scalars
446
+ return _rvs1(*args, size, random_state)
447
+
448
+ out = np.empty(size)
449
+
450
+ # out.shape can mix dimensions associated with arg_shape and _rvs1_size
451
+ # Sort them to arg_shape + _rvs1_size for easy indexing of dimensions
452
+ # corresponding with the different sets of scalar args
453
+ j0 = np.arange(out.ndim)
454
+ j1 = np.hstack((j0[~_rvs1_indices], j0[_rvs1_indices]))
455
+ out = np.moveaxis(out, j1, j0)
456
+
457
+ for i in np.ndindex(*size[~_rvs1_indices]):
458
+ # arg can be squeezed because singleton dimensions will be
459
+ # associated with _rvs1_size, not arg_shape per _check_shape
460
+ out[i] = _rvs1(*[np.squeeze(arg)[i] for arg in args],
461
+ _rvs1_size, random_state)
462
+
463
+ return np.moveaxis(out, j0, j1) # move axes back before returning
464
+ return _rvs
465
+
466
+
467
+ def _fit_determine_optimizer(optimizer):
468
+ if not callable(optimizer) and isinstance(optimizer, str):
469
+ if not optimizer.startswith('fmin_'):
470
+ optimizer = "fmin_"+optimizer
471
+ if optimizer == 'fmin_':
472
+ optimizer = 'fmin'
473
+ try:
474
+ optimizer = getattr(optimize, optimizer)
475
+ except AttributeError as e:
476
+ raise ValueError(f"{optimizer} is not a valid optimizer") from e
477
+ return optimizer
478
+
479
+ def _isintegral(x):
480
+ return x == np.round(x)
481
+
482
+ def _sum_finite(x):
483
+ """
484
+ For a 1D array x, return a tuple containing the sum of the
485
+ finite values of x and the number of nonfinite values.
486
+
487
+ This is a utility function used when evaluating the negative
488
+ loglikelihood for a distribution and an array of samples.
489
+
490
+ Examples
491
+ --------
492
+ >>> import numpy as np
493
+ >>> from scipy.stats._distn_infrastructure import _sum_finite
494
+ >>> tot, nbad = _sum_finite(np.array([-2, -np.inf, 5, 1]))
495
+ >>> tot
496
+ 4.0
497
+ >>> nbad
498
+ 1
499
+ """
500
+ finite_x = np.isfinite(x)
501
+ bad_count = finite_x.size - np.count_nonzero(finite_x)
502
+ return np.sum(x[finite_x]), bad_count
503
+
504
+
505
+ # Frozen RV class
506
+ class rv_frozen:
507
+
508
+ def __init__(self, dist, *args, **kwds):
509
+ self.args = args
510
+ self.kwds = kwds
511
+
512
+ # create a new instance
513
+ self.dist = dist.__class__(**dist._updated_ctor_param())
514
+
515
+ shapes, _, _ = self.dist._parse_args(*args, **kwds)
516
+ self.a, self.b = self.dist._get_support(*shapes)
517
+
518
+ @property
519
+ def random_state(self):
520
+ return self.dist._random_state
521
+
522
+ @random_state.setter
523
+ def random_state(self, seed):
524
+ self.dist._random_state = check_random_state(seed)
525
+
526
+ def cdf(self, x):
527
+ return self.dist.cdf(x, *self.args, **self.kwds)
528
+
529
+ def logcdf(self, x):
530
+ return self.dist.logcdf(x, *self.args, **self.kwds)
531
+
532
+ def ppf(self, q):
533
+ return self.dist.ppf(q, *self.args, **self.kwds)
534
+
535
+ def isf(self, q):
536
+ return self.dist.isf(q, *self.args, **self.kwds)
537
+
538
+ def rvs(self, size=None, random_state=None):
539
+ kwds = self.kwds.copy()
540
+ kwds.update({'size': size, 'random_state': random_state})
541
+ return self.dist.rvs(*self.args, **kwds)
542
+
543
+ def sf(self, x):
544
+ return self.dist.sf(x, *self.args, **self.kwds)
545
+
546
+ def logsf(self, x):
547
+ return self.dist.logsf(x, *self.args, **self.kwds)
548
+
549
+ def stats(self, moments='mv'):
550
+ kwds = self.kwds.copy()
551
+ kwds.update({'moments': moments})
552
+ return self.dist.stats(*self.args, **kwds)
553
+
554
+ def median(self):
555
+ return self.dist.median(*self.args, **self.kwds)
556
+
557
+ def mean(self):
558
+ return self.dist.mean(*self.args, **self.kwds)
559
+
560
+ def var(self):
561
+ return self.dist.var(*self.args, **self.kwds)
562
+
563
+ def std(self):
564
+ return self.dist.std(*self.args, **self.kwds)
565
+
566
+ def moment(self, order=None):
567
+ return self.dist.moment(order, *self.args, **self.kwds)
568
+
569
+ def entropy(self):
570
+ return self.dist.entropy(*self.args, **self.kwds)
571
+
572
+ def interval(self, confidence=None):
573
+ return self.dist.interval(confidence, *self.args, **self.kwds)
574
+
575
+ def expect(self, func=None, lb=None, ub=None, conditional=False, **kwds):
576
+ # expect method only accepts shape parameters as positional args
577
+ # hence convert self.args, self.kwds, also loc/scale
578
+ # See the .expect method docstrings for the meaning of
579
+ # other parameters.
580
+ a, loc, scale = self.dist._parse_args(*self.args, **self.kwds)
581
+ if isinstance(self.dist, rv_discrete):
582
+ return self.dist.expect(func, a, loc, lb, ub, conditional, **kwds)
583
+ else:
584
+ return self.dist.expect(func, a, loc, scale, lb, ub,
585
+ conditional, **kwds)
586
+
587
+ def support(self):
588
+ return self.dist.support(*self.args, **self.kwds)
589
+
590
+
591
+ class rv_discrete_frozen(rv_frozen):
592
+
593
+ def pmf(self, k):
594
+ return self.dist.pmf(k, *self.args, **self.kwds)
595
+
596
+ def logpmf(self, k): # No error
597
+ return self.dist.logpmf(k, *self.args, **self.kwds)
598
+
599
+
600
+ class rv_continuous_frozen(rv_frozen):
601
+
602
+ def pdf(self, x):
603
+ return self.dist.pdf(x, *self.args, **self.kwds)
604
+
605
+ def logpdf(self, x):
606
+ return self.dist.logpdf(x, *self.args, **self.kwds)
607
+
608
+
609
+ def argsreduce(cond, *args):
610
+ """Clean arguments to:
611
+
612
+ 1. Ensure all arguments are iterable (arrays of dimension at least one
613
+ 2. If cond != True and size > 1, ravel(args[i]) where ravel(condition) is
614
+ True, in 1D.
615
+
616
+ Return list of processed arguments.
617
+
618
+ Examples
619
+ --------
620
+ >>> import numpy as np
621
+ >>> from scipy.stats._distn_infrastructure import argsreduce
622
+ >>> rng = np.random.default_rng()
623
+ >>> A = rng.random((4, 5))
624
+ >>> B = 2
625
+ >>> C = rng.random((1, 5))
626
+ >>> cond = np.ones(A.shape)
627
+ >>> [A1, B1, C1] = argsreduce(cond, A, B, C)
628
+ >>> A1.shape
629
+ (4, 5)
630
+ >>> B1.shape
631
+ (1,)
632
+ >>> C1.shape
633
+ (1, 5)
634
+ >>> cond[2,:] = 0
635
+ >>> [A1, B1, C1] = argsreduce(cond, A, B, C)
636
+ >>> A1.shape
637
+ (15,)
638
+ >>> B1.shape
639
+ (1,)
640
+ >>> C1.shape
641
+ (15,)
642
+
643
+ """
644
+ # some distributions assume arguments are iterable.
645
+ newargs = np.atleast_1d(*args)
646
+
647
+ # np.atleast_1d returns an array if only one argument, or a list of arrays
648
+ # if more than one argument.
649
+ if not isinstance(newargs, (list | tuple)):
650
+ newargs = (newargs,)
651
+
652
+ if np.all(cond):
653
+ # broadcast arrays with cond
654
+ *newargs, cond = np.broadcast_arrays(*newargs, cond)
655
+ return [arg.ravel() for arg in newargs]
656
+
657
+ s = cond.shape
658
+ # np.extract returns flattened arrays, which are not broadcastable together
659
+ # unless they are either the same size or size == 1.
660
+ return [(arg if np.size(arg) == 1
661
+ else np.extract(cond, np.broadcast_to(arg, s)))
662
+ for arg in newargs]
663
+
664
+
665
+ parse_arg_template = """
666
+ def _parse_args(self, %(shape_arg_str)s %(locscale_in)s):
667
+ return (%(shape_arg_str)s), %(locscale_out)s
668
+
669
+ def _parse_args_rvs(self, %(shape_arg_str)s %(locscale_in)s, size=None):
670
+ return self._argcheck_rvs(%(shape_arg_str)s %(locscale_out)s, size=size)
671
+
672
+ def _parse_args_stats(self, %(shape_arg_str)s %(locscale_in)s, moments='mv'):
673
+ return (%(shape_arg_str)s), %(locscale_out)s, moments
674
+ """
675
+
676
+
677
+ class rv_generic:
678
+ """Class which encapsulates common functionality between rv_discrete
679
+ and rv_continuous.
680
+
681
+ """
682
+
683
+ def __init__(self, seed=None):
684
+ super().__init__()
685
+
686
+ # figure out if _stats signature has 'moments' keyword
687
+ sig = _getfullargspec(self._stats)
688
+ self._stats_has_moments = ((sig.varkw is not None) or
689
+ ('moments' in sig.args) or
690
+ ('moments' in sig.kwonlyargs))
691
+ self._random_state = check_random_state(seed)
692
+
693
+ @property
694
+ def random_state(self):
695
+ """Get or set the generator object for generating random variates.
696
+
697
+ If `random_state` is None (or `np.random`), the
698
+ `numpy.random.RandomState` singleton is used.
699
+ If `random_state` is an int, a new ``RandomState`` instance is used,
700
+ seeded with `random_state`.
701
+ If `random_state` is already a ``Generator`` or ``RandomState``
702
+ instance, that instance is used.
703
+
704
+ """
705
+ return self._random_state
706
+
707
+ @random_state.setter
708
+ def random_state(self, seed):
709
+ self._random_state = check_random_state(seed)
710
+
711
+ def __setstate__(self, state):
712
+ try:
713
+ self.__dict__.update(state)
714
+ # attaches the dynamically created methods on each instance.
715
+ # if a subclass overrides rv_generic.__setstate__, or implements
716
+ # it's own _attach_methods, then it must make sure that
717
+ # _attach_argparser_methods is called.
718
+ self._attach_methods()
719
+ except ValueError:
720
+ # reconstitute an old pickle scipy<1.6, that contains
721
+ # (_ctor_param, random_state) as state
722
+ self._ctor_param = state[0]
723
+ self._random_state = state[1]
724
+ self.__init__()
725
+
726
+ def _attach_methods(self):
727
+ """Attaches dynamically created methods to the rv_* instance.
728
+
729
+ This method must be overridden by subclasses, and must itself call
730
+ _attach_argparser_methods. This method is called in __init__ in
731
+ subclasses, and in __setstate__
732
+ """
733
+ raise NotImplementedError
734
+
735
+ def _attach_argparser_methods(self):
736
+ """
737
+ Generates the argument-parsing functions dynamically and attaches
738
+ them to the instance.
739
+
740
+ Should be called from `_attach_methods`, typically in __init__ and
741
+ during unpickling (__setstate__)
742
+ """
743
+ ns = {}
744
+ exec(self._parse_arg_template, ns)
745
+ # NB: attach to the instance, not class
746
+ for name in ['_parse_args', '_parse_args_stats', '_parse_args_rvs']:
747
+ setattr(self, name, types.MethodType(ns[name], self))
748
+
749
+ def _construct_argparser(
750
+ self, meths_to_inspect, locscale_in, locscale_out):
751
+ """Construct the parser string for the shape arguments.
752
+
753
+ This method should be called in __init__ of a class for each
754
+ distribution. It creates the `_parse_arg_template` attribute that is
755
+ then used by `_attach_argparser_methods` to dynamically create and
756
+ attach the `_parse_args`, `_parse_args_stats`, `_parse_args_rvs`
757
+ methods to the instance.
758
+
759
+ If self.shapes is a non-empty string, interprets it as a
760
+ comma-separated list of shape parameters.
761
+
762
+ Otherwise inspects the call signatures of `meths_to_inspect`
763
+ and constructs the argument-parsing functions from these.
764
+ In this case also sets `shapes` and `numargs`.
765
+ """
766
+
767
+ if self.shapes:
768
+ # sanitize the user-supplied shapes
769
+ if not isinstance(self.shapes, str):
770
+ raise TypeError('shapes must be a string.')
771
+
772
+ shapes = self.shapes.replace(',', ' ').split()
773
+
774
+ for field in shapes:
775
+ if keyword.iskeyword(field):
776
+ raise SyntaxError('keywords cannot be used as shapes.')
777
+ if not re.match('^[_a-zA-Z][_a-zA-Z0-9]*$', field):
778
+ raise SyntaxError(
779
+ 'shapes must be valid python identifiers')
780
+ else:
781
+ # find out the call signatures (_pdf, _cdf etc), deduce shape
782
+ # arguments. Generic methods only have 'self, x', any further args
783
+ # are shapes.
784
+ shapes_list = []
785
+ for meth in meths_to_inspect:
786
+ shapes_args = _getfullargspec(meth) # NB does not contain self
787
+ args = shapes_args.args[1:] # peel off 'x', too
788
+
789
+ if args:
790
+ shapes_list.append(args)
791
+
792
+ # *args or **kwargs are not allowed w/automatic shapes
793
+ if shapes_args.varargs is not None:
794
+ raise TypeError(
795
+ '*args are not allowed w/out explicit shapes')
796
+ if shapes_args.varkw is not None:
797
+ raise TypeError(
798
+ '**kwds are not allowed w/out explicit shapes')
799
+ if shapes_args.kwonlyargs:
800
+ raise TypeError(
801
+ 'kwonly args are not allowed w/out explicit shapes')
802
+ if shapes_args.defaults is not None:
803
+ raise TypeError('defaults are not allowed for shapes')
804
+
805
+ if shapes_list:
806
+ shapes = shapes_list[0]
807
+
808
+ # make sure the signatures are consistent
809
+ for item in shapes_list:
810
+ if item != shapes:
811
+ raise TypeError('Shape arguments are inconsistent.')
812
+ else:
813
+ shapes = []
814
+
815
+ # have the arguments, construct the method from template
816
+ shapes_str = ', '.join(shapes) + ', ' if shapes else '' # NB: not None
817
+ dct = dict(shape_arg_str=shapes_str,
818
+ locscale_in=locscale_in,
819
+ locscale_out=locscale_out,
820
+ )
821
+
822
+ # this string is used by _attach_argparser_methods
823
+ self._parse_arg_template = parse_arg_template % dct
824
+
825
+ self.shapes = ', '.join(shapes) if shapes else None
826
+ if not hasattr(self, 'numargs'):
827
+ # allows more general subclassing with *args
828
+ self.numargs = len(shapes)
829
+
830
+ def _construct_doc(self, docdict, shapes_vals=None):
831
+ """Construct the instance docstring with string substitutions."""
832
+ tempdict = docdict.copy()
833
+ tempdict['name'] = self.name or 'distname'
834
+ tempdict['shapes'] = self.shapes or ''
835
+
836
+ if shapes_vals is None:
837
+ shapes_vals = ()
838
+ try:
839
+ vals = ', '.join(f'{val:.3g}' for val in shapes_vals)
840
+ except TypeError:
841
+ vals = ', '.join(f'{val}' for val in shapes_vals)
842
+ tempdict['vals'] = vals
843
+
844
+ tempdict['shapes_'] = self.shapes or ''
845
+ if self.shapes and self.numargs == 1:
846
+ tempdict['shapes_'] += ','
847
+
848
+ if self.shapes:
849
+ tempdict['set_vals_stmt'] = f'>>> {self.shapes} = {vals}'
850
+ else:
851
+ tempdict['set_vals_stmt'] = ''
852
+
853
+ if self.shapes is None:
854
+ # remove shapes from call parameters if there are none
855
+ for item in ['default', 'before_notes']:
856
+ tempdict[item] = tempdict[item].replace(
857
+ "\n%(shapes)s : array_like\n shape parameters", "")
858
+ for i in range(2):
859
+ if self.shapes is None:
860
+ # necessary because we use %(shapes)s in two forms (w w/o ", ")
861
+ self.__doc__ = self.__doc__.replace("%(shapes)s, ", "")
862
+ try:
863
+ self.__doc__ = doccer.docformat(self.__doc__, tempdict)
864
+ except TypeError as e:
865
+ raise Exception("Unable to construct docstring for "
866
+ f"distribution \"{self.name}\": {repr(e)}") from e
867
+
868
+ # correct for empty shapes
869
+ self.__doc__ = self.__doc__.replace('(, ', '(').replace(', )', ')')
870
+
871
+ def _construct_default_doc(self, longname=None,
872
+ docdict=None, discrete='continuous'):
873
+ """Construct instance docstring from the default template."""
874
+ if longname is None:
875
+ longname = 'A'
876
+ self.__doc__ = ''.join([f'{longname} {discrete} random variable.',
877
+ '\n\n%(before_notes)s\n', docheaders['notes'],
878
+ '\n%(example)s'])
879
+ self._construct_doc(docdict)
880
+
881
+ def freeze(self, *args, **kwds):
882
+ """Freeze the distribution for the given arguments.
883
+
884
+ Parameters
885
+ ----------
886
+ arg1, arg2, arg3,... : array_like
887
+ The shape parameter(s) for the distribution. Should include all
888
+ the non-optional arguments, may include ``loc`` and ``scale``.
889
+
890
+ Returns
891
+ -------
892
+ rv_frozen : rv_frozen instance
893
+ The frozen distribution.
894
+
895
+ """
896
+ if isinstance(self, rv_continuous):
897
+ return rv_continuous_frozen(self, *args, **kwds)
898
+ else:
899
+ return rv_discrete_frozen(self, *args, **kwds)
900
+
901
+ def __call__(self, *args, **kwds):
902
+ return self.freeze(*args, **kwds)
903
+ __call__.__doc__ = freeze.__doc__
904
+
905
+ # The actual calculation functions (no basic checking need be done)
906
+ # If these are defined, the others won't be looked at.
907
+ # Otherwise, the other set can be defined.
908
+ def _stats(self, *args, **kwds):
909
+ return None, None, None, None
910
+
911
+ # Noncentral moments (also known as the moment about the origin).
912
+ # Expressed in LaTeX, munp would be $\mu'_{n}$, i.e. "mu-sub-n-prime".
913
+ # The primed mu is a widely used notation for the noncentral moment.
914
+ def _munp(self, n, *args):
915
+ # Silence floating point warnings from integration.
916
+ with np.errstate(all='ignore'):
917
+ vals = self.generic_moment(n, *args)
918
+ return vals
919
+
920
+ def _argcheck_rvs(self, *args, **kwargs):
921
+ # Handle broadcasting and size validation of the rvs method.
922
+ # Subclasses should not have to override this method.
923
+ # The rule is that if `size` is not None, then `size` gives the
924
+ # shape of the result (integer values of `size` are treated as
925
+ # tuples with length 1; i.e. `size=3` is the same as `size=(3,)`.)
926
+ #
927
+ # `args` is expected to contain the shape parameters (if any), the
928
+ # location and the scale in a flat tuple (e.g. if there are two
929
+ # shape parameters `a` and `b`, `args` will be `(a, b, loc, scale)`).
930
+ # The only keyword argument expected is 'size'.
931
+ size = kwargs.get('size', None)
932
+ all_bcast = np.broadcast_arrays(*args)
933
+
934
+ def squeeze_left(a):
935
+ while a.ndim > 0 and a.shape[0] == 1:
936
+ a = a[0]
937
+ return a
938
+
939
+ # Eliminate trivial leading dimensions. In the convention
940
+ # used by numpy's random variate generators, trivial leading
941
+ # dimensions are effectively ignored. In other words, when `size`
942
+ # is given, trivial leading dimensions of the broadcast parameters
943
+ # in excess of the number of dimensions in size are ignored, e.g.
944
+ # >>> np.random.normal([[1, 3, 5]], [[[[0.01]]]], size=3)
945
+ # array([ 1.00104267, 3.00422496, 4.99799278])
946
+ # If `size` is not given, the exact broadcast shape is preserved:
947
+ # >>> np.random.normal([[1, 3, 5]], [[[[0.01]]]])
948
+ # array([[[[ 1.00862899, 3.00061431, 4.99867122]]]])
949
+ #
950
+ all_bcast = [squeeze_left(a) for a in all_bcast]
951
+ bcast_shape = all_bcast[0].shape
952
+ bcast_ndim = all_bcast[0].ndim
953
+
954
+ if size is None:
955
+ size_ = bcast_shape
956
+ else:
957
+ size_ = tuple(np.atleast_1d(size))
958
+
959
+ # Check compatibility of size_ with the broadcast shape of all
960
+ # the parameters. This check is intended to be consistent with
961
+ # how the numpy random variate generators (e.g. np.random.normal,
962
+ # np.random.beta) handle their arguments. The rule is that, if size
963
+ # is given, it determines the shape of the output. Broadcasting
964
+ # can't change the output size.
965
+
966
+ # This is the standard broadcasting convention of extending the
967
+ # shape with fewer dimensions with enough dimensions of length 1
968
+ # so that the two shapes have the same number of dimensions.
969
+ ndiff = bcast_ndim - len(size_)
970
+ if ndiff < 0:
971
+ bcast_shape = (1,)*(-ndiff) + bcast_shape
972
+ elif ndiff > 0:
973
+ size_ = (1,)*ndiff + size_
974
+
975
+ # This compatibility test is not standard. In "regular" broadcasting,
976
+ # two shapes are compatible if for each dimension, the lengths are the
977
+ # same or one of the lengths is 1. Here, the length of a dimension in
978
+ # size_ must not be less than the corresponding length in bcast_shape.
979
+ ok = all([bcdim == 1 or bcdim == szdim
980
+ for (bcdim, szdim) in zip(bcast_shape, size_)])
981
+ if not ok:
982
+ raise ValueError("size does not match the broadcast shape of "
983
+ f"the parameters. {size}, {size_}, {bcast_shape}")
984
+
985
+ param_bcast = all_bcast[:-2]
986
+ loc_bcast = all_bcast[-2]
987
+ scale_bcast = all_bcast[-1]
988
+
989
+ return param_bcast, loc_bcast, scale_bcast, size_
990
+
991
+ # These are the methods you must define (standard form functions)
992
+ # NB: generic _pdf, _logpdf, _cdf are different for
993
+ # rv_continuous and rv_discrete hence are defined in there
994
+ def _argcheck(self, *args):
995
+ """Default check for correct values on args and keywords.
996
+
997
+ Returns condition array of 1's where arguments are correct and
998
+ 0's where they are not.
999
+
1000
+ """
1001
+ cond = 1
1002
+ for arg in args:
1003
+ cond = logical_and(cond, (asarray(arg) > 0))
1004
+ return cond
1005
+
1006
+ def _get_support(self, *args, **kwargs):
1007
+ """Return the support of the (unscaled, unshifted) distribution.
1008
+
1009
+ *Must* be overridden by distributions which have support dependent
1010
+ upon the shape parameters of the distribution. Any such override
1011
+ *must not* set or change any of the class members, as these members
1012
+ are shared amongst all instances of the distribution.
1013
+
1014
+ Parameters
1015
+ ----------
1016
+ arg1, arg2, ... : array_like
1017
+ The shape parameter(s) for the distribution (see docstring of the
1018
+ instance object for more information).
1019
+
1020
+ Returns
1021
+ -------
1022
+ a, b : numeric (float, or int or +/-np.inf)
1023
+ end-points of the distribution's support for the specified
1024
+ shape parameters.
1025
+ """
1026
+ return self.a, self.b
1027
+
1028
+ def _support_mask(self, x, *args):
1029
+ a, b = self._get_support(*args)
1030
+ with np.errstate(invalid='ignore'):
1031
+ return (a <= x) & (x <= b)
1032
+
1033
+ def _open_support_mask(self, x, *args):
1034
+ a, b = self._get_support(*args)
1035
+ with np.errstate(invalid='ignore'):
1036
+ return (a < x) & (x < b)
1037
+
1038
+ def _rvs(self, *args, size=None, random_state=None):
1039
+ # This method must handle size being a tuple, and it must
1040
+ # properly broadcast *args and size. size might be
1041
+ # an empty tuple, which means a scalar random variate is to be
1042
+ # generated.
1043
+
1044
+ # Use basic inverse cdf algorithm for RV generation as default.
1045
+ U = random_state.uniform(size=size)
1046
+ Y = self._ppf(U, *args)
1047
+ return Y
1048
+
1049
+ def _logcdf(self, x, *args):
1050
+ with np.errstate(divide='ignore'):
1051
+ return log(self._cdf(x, *args))
1052
+
1053
+ def _sf(self, x, *args):
1054
+ return 1.0-self._cdf(x, *args)
1055
+
1056
+ def _logsf(self, x, *args):
1057
+ with np.errstate(divide='ignore'):
1058
+ return log(self._sf(x, *args))
1059
+
1060
+ def _ppf(self, q, *args):
1061
+ return self._ppfvec(q, *args)
1062
+
1063
+ def _isf(self, q, *args):
1064
+ return self._ppf(1.0-q, *args) # use correct _ppf for subclasses
1065
+
1066
+ # These are actually called, and should not be overwritten if you
1067
+ # want to keep error checking.
1068
+ def rvs(self, *args, **kwds):
1069
+ """Random variates of given type.
1070
+
1071
+ Parameters
1072
+ ----------
1073
+ arg1, arg2, arg3,... : array_like
1074
+ The shape parameter(s) for the distribution (see docstring of the
1075
+ instance object for more information).
1076
+ loc : array_like, optional
1077
+ Location parameter (default=0).
1078
+ scale : array_like, optional
1079
+ Scale parameter (default=1).
1080
+ size : int or tuple of ints, optional
1081
+ Defining number of random variates (default is 1).
1082
+ random_state : {None, int, `numpy.random.Generator`,
1083
+ `numpy.random.RandomState`}, optional
1084
+
1085
+ If `random_state` is None (or `np.random`), the
1086
+ `numpy.random.RandomState` singleton is used.
1087
+ If `random_state` is an int, a new ``RandomState`` instance is
1088
+ used, seeded with `random_state`.
1089
+ If `random_state` is already a ``Generator`` or ``RandomState``
1090
+ instance, that instance is used.
1091
+
1092
+ Returns
1093
+ -------
1094
+ rvs : ndarray or scalar
1095
+ Random variates of given `size`.
1096
+
1097
+ """
1098
+ discrete = kwds.pop('discrete', None)
1099
+ rndm = kwds.pop('random_state', None)
1100
+ args, loc, scale, size = self._parse_args_rvs(*args, **kwds)
1101
+ cond = logical_and(self._argcheck(*args), (scale >= 0))
1102
+ if not np.all(cond):
1103
+ message = ("Domain error in arguments. The `scale` parameter must "
1104
+ "be positive for all distributions, and many "
1105
+ "distributions have restrictions on shape parameters. "
1106
+ f"Please see the `scipy.stats.{self.name}` "
1107
+ "documentation for details.")
1108
+ raise ValueError(message)
1109
+
1110
+ if np.all(scale == 0):
1111
+ return loc*ones(size, 'd')
1112
+
1113
+ # extra gymnastics needed for a custom random_state
1114
+ if rndm is not None:
1115
+ random_state_saved = self._random_state
1116
+ random_state = check_random_state(rndm)
1117
+ else:
1118
+ random_state = self._random_state
1119
+
1120
+ vals = self._rvs(*args, size=size, random_state=random_state)
1121
+
1122
+ vals = vals * scale + loc
1123
+
1124
+ # do not forget to restore the _random_state
1125
+ if rndm is not None:
1126
+ self._random_state = random_state_saved
1127
+
1128
+ # Cast to int if discrete
1129
+ if discrete and not isinstance(self, rv_sample):
1130
+ if size == ():
1131
+ vals = int(vals)
1132
+ else:
1133
+ vals = vals.astype(np.int64)
1134
+
1135
+ return vals
1136
+
1137
+ def stats(self, *args, **kwds):
1138
+ """Some statistics of the given RV.
1139
+
1140
+ Parameters
1141
+ ----------
1142
+ arg1, arg2, arg3,... : array_like
1143
+ The shape parameter(s) for the distribution (see docstring of the
1144
+ instance object for more information)
1145
+ loc : array_like, optional
1146
+ location parameter (default=0)
1147
+ scale : array_like, optional (continuous RVs only)
1148
+ scale parameter (default=1)
1149
+ moments : str, optional
1150
+ composed of letters ['mvsk'] defining which moments to compute:
1151
+ 'm' = mean,
1152
+ 'v' = variance,
1153
+ 's' = (Fisher's) skew,
1154
+ 'k' = (Fisher's) kurtosis.
1155
+ (default is 'mv')
1156
+
1157
+ Returns
1158
+ -------
1159
+ stats : sequence
1160
+ of requested moments.
1161
+
1162
+ """
1163
+ args, loc, scale, moments = self._parse_args_stats(*args, **kwds)
1164
+ # scale = 1 by construction for discrete RVs
1165
+ loc, scale = map(asarray, (loc, scale))
1166
+ args = tuple(map(asarray, args))
1167
+ cond = self._argcheck(*args) & (scale > 0) & (loc == loc)
1168
+ output = []
1169
+ default = np.full(shape(cond), fill_value=self.badvalue)
1170
+
1171
+ # Use only entries that are valid in calculation
1172
+ if np.any(cond):
1173
+ goodargs = argsreduce(cond, *(args+(scale, loc)))
1174
+ scale, loc, goodargs = goodargs[-2], goodargs[-1], goodargs[:-2]
1175
+
1176
+ if self._stats_has_moments:
1177
+ mu, mu2, g1, g2 = self._stats(*goodargs,
1178
+ **{'moments': moments})
1179
+ else:
1180
+ mu, mu2, g1, g2 = self._stats(*goodargs)
1181
+
1182
+ if 'm' in moments:
1183
+ if mu is None:
1184
+ mu = self._munp(1, *goodargs)
1185
+ out0 = default.copy()
1186
+ place(out0, cond, mu * scale + loc)
1187
+ output.append(out0)
1188
+
1189
+ if 'v' in moments:
1190
+ if mu2 is None:
1191
+ mu2p = self._munp(2, *goodargs)
1192
+ if mu is None:
1193
+ mu = self._munp(1, *goodargs)
1194
+ # if mean is inf then var is also inf
1195
+ with np.errstate(invalid='ignore'):
1196
+ mu2 = np.where(~np.isinf(mu), mu2p - mu**2, np.inf)
1197
+ out0 = default.copy()
1198
+ place(out0, cond, mu2 * scale * scale)
1199
+ output.append(out0)
1200
+
1201
+ if 's' in moments:
1202
+ if g1 is None:
1203
+ mu3p = self._munp(3, *goodargs)
1204
+ if mu is None:
1205
+ mu = self._munp(1, *goodargs)
1206
+ if mu2 is None:
1207
+ mu2p = self._munp(2, *goodargs)
1208
+ with np.errstate(invalid='ignore'):
1209
+ mu2 = mu2p - mu * mu
1210
+ with np.errstate(invalid='ignore'):
1211
+ mu3 = (-mu*mu - 3*mu2)*mu + mu3p
1212
+ g1 = mu3 / np.power(mu2, 1.5)
1213
+ out0 = default.copy()
1214
+ place(out0, cond, g1)
1215
+ output.append(out0)
1216
+
1217
+ if 'k' in moments:
1218
+ if g2 is None:
1219
+ mu4p = self._munp(4, *goodargs)
1220
+ if mu is None:
1221
+ mu = self._munp(1, *goodargs)
1222
+ if mu2 is None:
1223
+ mu2p = self._munp(2, *goodargs)
1224
+ with np.errstate(invalid='ignore'):
1225
+ mu2 = mu2p - mu * mu
1226
+ if g1 is None:
1227
+ mu3 = None
1228
+ else:
1229
+ # (mu2**1.5) breaks down for nan and inf
1230
+ mu3 = g1 * np.power(mu2, 1.5)
1231
+ if mu3 is None:
1232
+ mu3p = self._munp(3, *goodargs)
1233
+ with np.errstate(invalid='ignore'):
1234
+ mu3 = (-mu * mu - 3 * mu2) * mu + mu3p
1235
+ with np.errstate(invalid='ignore'):
1236
+ mu4 = ((-mu**2 - 6*mu2) * mu - 4*mu3)*mu + mu4p
1237
+ g2 = mu4 / mu2**2.0 - 3.0
1238
+ out0 = default.copy()
1239
+ place(out0, cond, g2)
1240
+ output.append(out0)
1241
+ else: # no valid args
1242
+ output = [default.copy() for _ in moments]
1243
+
1244
+ output = [out[()] for out in output]
1245
+ if len(output) == 1:
1246
+ return output[0]
1247
+ else:
1248
+ return tuple(output)
1249
+
1250
+ def entropy(self, *args, **kwds):
1251
+ """Differential entropy of the RV.
1252
+
1253
+ Parameters
1254
+ ----------
1255
+ arg1, arg2, arg3,... : array_like
1256
+ The shape parameter(s) for the distribution (see docstring of the
1257
+ instance object for more information).
1258
+ loc : array_like, optional
1259
+ Location parameter (default=0).
1260
+ scale : array_like, optional (continuous distributions only).
1261
+ Scale parameter (default=1).
1262
+
1263
+ Notes
1264
+ -----
1265
+ Entropy is defined base `e`:
1266
+
1267
+ >>> import numpy as np
1268
+ >>> from scipy.stats._distn_infrastructure import rv_discrete
1269
+ >>> drv = rv_discrete(values=((0, 1), (0.5, 0.5)))
1270
+ >>> np.allclose(drv.entropy(), np.log(2.0))
1271
+ True
1272
+
1273
+ """
1274
+ args, loc, scale = self._parse_args(*args, **kwds)
1275
+ # NB: for discrete distributions scale=1 by construction in _parse_args
1276
+ loc, scale = map(asarray, (loc, scale))
1277
+ args = tuple(map(asarray, args))
1278
+ cond0 = self._argcheck(*args) & (scale > 0) & (loc == loc)
1279
+ output = zeros(shape(cond0), 'd')
1280
+ place(output, (1-cond0), self.badvalue)
1281
+ goodargs = argsreduce(cond0, scale, *args)
1282
+ goodscale = goodargs[0]
1283
+ goodargs = goodargs[1:]
1284
+ place(output, cond0, self.vecentropy(*goodargs) + log(goodscale))
1285
+ return output[()]
1286
+
1287
+ def moment(self, order, *args, **kwds):
1288
+ """non-central moment of distribution of specified order.
1289
+
1290
+ Parameters
1291
+ ----------
1292
+ order : int, order >= 1
1293
+ Order of moment.
1294
+ arg1, arg2, arg3,... : float
1295
+ The shape parameter(s) for the distribution (see docstring of the
1296
+ instance object for more information).
1297
+ loc : array_like, optional
1298
+ location parameter (default=0)
1299
+ scale : array_like, optional
1300
+ scale parameter (default=1)
1301
+
1302
+ """
1303
+ n = order
1304
+ shapes, loc, scale = self._parse_args(*args, **kwds)
1305
+ args = np.broadcast_arrays(*(*shapes, loc, scale))
1306
+ *shapes, loc, scale = args
1307
+
1308
+ i0 = np.logical_and(self._argcheck(*shapes), scale > 0)
1309
+ i1 = np.logical_and(i0, loc == 0)
1310
+ i2 = np.logical_and(i0, loc != 0)
1311
+
1312
+ args = argsreduce(i0, *shapes, loc, scale)
1313
+ *shapes, loc, scale = args
1314
+
1315
+ if (floor(n) != n):
1316
+ raise ValueError("Moment must be an integer.")
1317
+ if (n < 0):
1318
+ raise ValueError("Moment must be positive.")
1319
+ mu, mu2, g1, g2 = None, None, None, None
1320
+ if (n > 0) and (n < 5):
1321
+ if self._stats_has_moments:
1322
+ mdict = {'moments': {1: 'm', 2: 'v', 3: 'vs', 4: 'mvsk'}[n]}
1323
+ else:
1324
+ mdict = {}
1325
+ mu, mu2, g1, g2 = self._stats(*shapes, **mdict)
1326
+ val = np.empty(loc.shape) # val needs to be indexed by loc
1327
+ val[...] = _moment_from_stats(n, mu, mu2, g1, g2, self._munp, shapes)
1328
+
1329
+ # Convert to transformed X = L + S*Y
1330
+ # E[X^n] = E[(L+S*Y)^n] = L^n sum(comb(n, k)*(S/L)^k E[Y^k], k=0...n)
1331
+ result = zeros(i0.shape)
1332
+ place(result, ~i0, self.badvalue)
1333
+
1334
+ if i1.any():
1335
+ res1 = scale[loc == 0]**n * val[loc == 0]
1336
+ place(result, i1, res1)
1337
+
1338
+ if i2.any():
1339
+ mom = [mu, mu2, g1, g2]
1340
+ arrs = [i for i in mom if i is not None]
1341
+ idx = [i for i in range(4) if mom[i] is not None]
1342
+ if any(idx):
1343
+ arrs = argsreduce(loc != 0, *arrs)
1344
+ j = 0
1345
+ for i in idx:
1346
+ mom[i] = arrs[j]
1347
+ j += 1
1348
+ mu, mu2, g1, g2 = mom
1349
+ args = argsreduce(loc != 0, *shapes, loc, scale, val)
1350
+ *shapes, loc, scale, val = args
1351
+
1352
+ res2 = zeros(loc.shape, dtype='d')
1353
+ fac = scale / loc
1354
+ for k in range(n):
1355
+ valk = _moment_from_stats(k, mu, mu2, g1, g2, self._munp,
1356
+ shapes)
1357
+ res2 += comb(n, k, exact=True)*fac**k * valk
1358
+ res2 += fac**n * val
1359
+ res2 *= loc**n
1360
+ place(result, i2, res2)
1361
+
1362
+ return result[()]
1363
+
1364
+ def median(self, *args, **kwds):
1365
+ """Median of the distribution.
1366
+
1367
+ Parameters
1368
+ ----------
1369
+ arg1, arg2, arg3,... : array_like
1370
+ The shape parameter(s) for the distribution (see docstring of the
1371
+ instance object for more information)
1372
+ loc : array_like, optional
1373
+ Location parameter, Default is 0.
1374
+ scale : array_like, optional
1375
+ Scale parameter, Default is 1.
1376
+
1377
+ Returns
1378
+ -------
1379
+ median : float
1380
+ The median of the distribution.
1381
+
1382
+ See Also
1383
+ --------
1384
+ rv_discrete.ppf
1385
+ Inverse of the CDF
1386
+
1387
+ """
1388
+ return self.ppf(0.5, *args, **kwds)
1389
+
1390
+ def mean(self, *args, **kwds):
1391
+ """Mean of the distribution.
1392
+
1393
+ Parameters
1394
+ ----------
1395
+ arg1, arg2, arg3,... : array_like
1396
+ The shape parameter(s) for the distribution (see docstring of the
1397
+ instance object for more information)
1398
+ loc : array_like, optional
1399
+ location parameter (default=0)
1400
+ scale : array_like, optional
1401
+ scale parameter (default=1)
1402
+
1403
+ Returns
1404
+ -------
1405
+ mean : float
1406
+ the mean of the distribution
1407
+
1408
+ """
1409
+ kwds['moments'] = 'm'
1410
+ res = self.stats(*args, **kwds)
1411
+ if isinstance(res, ndarray) and res.ndim == 0:
1412
+ return res[()]
1413
+ return res
1414
+
1415
+ def var(self, *args, **kwds):
1416
+ """Variance of the distribution.
1417
+
1418
+ Parameters
1419
+ ----------
1420
+ arg1, arg2, arg3,... : array_like
1421
+ The shape parameter(s) for the distribution (see docstring of the
1422
+ instance object for more information)
1423
+ loc : array_like, optional
1424
+ location parameter (default=0)
1425
+ scale : array_like, optional
1426
+ scale parameter (default=1)
1427
+
1428
+ Returns
1429
+ -------
1430
+ var : float
1431
+ the variance of the distribution
1432
+
1433
+ """
1434
+ kwds['moments'] = 'v'
1435
+ res = self.stats(*args, **kwds)
1436
+ if isinstance(res, ndarray) and res.ndim == 0:
1437
+ return res[()]
1438
+ return res
1439
+
1440
+ def std(self, *args, **kwds):
1441
+ """Standard deviation of the distribution.
1442
+
1443
+ Parameters
1444
+ ----------
1445
+ arg1, arg2, arg3,... : array_like
1446
+ The shape parameter(s) for the distribution (see docstring of the
1447
+ instance object for more information)
1448
+ loc : array_like, optional
1449
+ location parameter (default=0)
1450
+ scale : array_like, optional
1451
+ scale parameter (default=1)
1452
+
1453
+ Returns
1454
+ -------
1455
+ std : float
1456
+ standard deviation of the distribution
1457
+
1458
+ """
1459
+ kwds['moments'] = 'v'
1460
+ res = sqrt(self.stats(*args, **kwds))
1461
+ return res
1462
+
1463
+ def interval(self, confidence, *args, **kwds):
1464
+ """Confidence interval with equal areas around the median.
1465
+
1466
+ Parameters
1467
+ ----------
1468
+ confidence : array_like of float
1469
+ Probability that an rv will be drawn from the returned range.
1470
+ Each value should be in the range [0, 1].
1471
+ arg1, arg2, ... : array_like
1472
+ The shape parameter(s) for the distribution (see docstring of the
1473
+ instance object for more information).
1474
+ loc : array_like, optional
1475
+ location parameter, Default is 0.
1476
+ scale : array_like, optional
1477
+ scale parameter, Default is 1.
1478
+
1479
+ Returns
1480
+ -------
1481
+ a, b : ndarray of float
1482
+ end-points of range that contain ``100 * alpha %`` of the rv's
1483
+ possible values.
1484
+
1485
+ Notes
1486
+ -----
1487
+ This is implemented as ``ppf([p_tail, 1-p_tail])``, where
1488
+ ``ppf`` is the inverse cumulative distribution function and
1489
+ ``p_tail = (1-confidence)/2``. Suppose ``[c, d]`` is the support of a
1490
+ discrete distribution; then ``ppf([0, 1]) == (c-1, d)``. Therefore,
1491
+ when ``confidence=1`` and the distribution is discrete, the left end
1492
+ of the interval will be beyond the support of the distribution.
1493
+ For discrete distributions, the interval will limit the probability
1494
+ in each tail to be less than or equal to ``p_tail`` (usually
1495
+ strictly less).
1496
+
1497
+ """
1498
+ alpha = confidence
1499
+
1500
+ alpha = asarray(alpha)
1501
+ if np.any((alpha > 1) | (alpha < 0)):
1502
+ raise ValueError("alpha must be between 0 and 1 inclusive")
1503
+ q1 = (1.0-alpha)/2
1504
+ q2 = (1.0+alpha)/2
1505
+ a = self.ppf(q1, *args, **kwds)
1506
+ b = self.ppf(q2, *args, **kwds)
1507
+ return a, b
1508
+
1509
+ def support(self, *args, **kwargs):
1510
+ """Support of the distribution.
1511
+
1512
+ Parameters
1513
+ ----------
1514
+ arg1, arg2, ... : array_like
1515
+ The shape parameter(s) for the distribution (see docstring of the
1516
+ instance object for more information).
1517
+ loc : array_like, optional
1518
+ location parameter, Default is 0.
1519
+ scale : array_like, optional
1520
+ scale parameter, Default is 1.
1521
+
1522
+ Returns
1523
+ -------
1524
+ a, b : array_like
1525
+ end-points of the distribution's support.
1526
+
1527
+ """
1528
+ args, loc, scale = self._parse_args(*args, **kwargs)
1529
+ arrs = np.broadcast_arrays(*args, loc, scale)
1530
+ args, loc, scale = arrs[:-2], arrs[-2], arrs[-1]
1531
+ cond = self._argcheck(*args) & (scale > 0)
1532
+ _a, _b = self._get_support(*args)
1533
+ if cond.all():
1534
+ return _a * scale + loc, _b * scale + loc
1535
+ elif cond.ndim == 0:
1536
+ return self.badvalue, self.badvalue
1537
+ # promote bounds to at least float to fill in the badvalue
1538
+ _a, _b = np.asarray(_a).astype('d'), np.asarray(_b).astype('d')
1539
+ out_a, out_b = _a * scale + loc, _b * scale + loc
1540
+ place(out_a, 1-cond, self.badvalue)
1541
+ place(out_b, 1-cond, self.badvalue)
1542
+ return out_a, out_b
1543
+
1544
+ def nnlf(self, theta, x):
1545
+ """Negative loglikelihood function.
1546
+ Notes
1547
+ -----
1548
+ This is ``-sum(log pdf(x, theta), axis=0)`` where `theta` are the
1549
+ parameters (including loc and scale).
1550
+ """
1551
+ loc, scale, args = self._unpack_loc_scale(theta)
1552
+ if not self._argcheck(*args) or scale <= 0:
1553
+ return inf
1554
+ x = (asarray(x)-loc) / scale
1555
+ n_log_scale = len(x) * log(scale)
1556
+ if np.any(~self._support_mask(x, *args)):
1557
+ return inf
1558
+ return self._nnlf(x, *args) + n_log_scale
1559
+
1560
+ def _nnlf(self, x, *args):
1561
+ return -np.sum(self._logpxf(x, *args), axis=0)
1562
+
1563
+ def _nlff_and_penalty(self, x, args, log_fitfun):
1564
+ # negative log fit function
1565
+ cond0 = ~self._support_mask(x, *args)
1566
+ n_bad = np.count_nonzero(cond0, axis=0)
1567
+ if n_bad > 0:
1568
+ x = argsreduce(~cond0, x)[0]
1569
+ logff = log_fitfun(x, *args)
1570
+ finite_logff = np.isfinite(logff)
1571
+ n_bad += np.sum(~finite_logff, axis=0)
1572
+ if n_bad > 0:
1573
+ penalty = n_bad * log(_XMAX) * 100
1574
+ return -np.sum(logff[finite_logff], axis=0) + penalty
1575
+ return -np.sum(logff, axis=0)
1576
+
1577
+ def _penalized_nnlf(self, theta, x):
1578
+ """Penalized negative loglikelihood function.
1579
+ i.e., - sum (log pdf(x, theta), axis=0) + penalty
1580
+ where theta are the parameters (including loc and scale)
1581
+ """
1582
+ loc, scale, args = self._unpack_loc_scale(theta)
1583
+ if not self._argcheck(*args) or scale <= 0:
1584
+ return inf
1585
+ x = asarray((x-loc) / scale)
1586
+ n_log_scale = len(x) * log(scale)
1587
+ return self._nlff_and_penalty(x, args, self._logpxf) + n_log_scale
1588
+
1589
+ def _penalized_nlpsf(self, theta, x):
1590
+ """Penalized negative log product spacing function.
1591
+ i.e., - sum (log (diff (cdf (x, theta))), axis=0) + penalty
1592
+ where theta are the parameters (including loc and scale)
1593
+ Follows reference [1] of scipy.stats.fit
1594
+ """
1595
+ loc, scale, args = self._unpack_loc_scale(theta)
1596
+ if not self._argcheck(*args) or scale <= 0:
1597
+ return inf
1598
+ x = (np.sort(x) - loc)/scale
1599
+
1600
+ def log_psf(x, *args):
1601
+ x, lj = np.unique(x, return_counts=True) # fast for sorted x
1602
+ cdf_data = self._cdf(x, *args) if x.size else []
1603
+ if not (x.size and 1 - cdf_data[-1] <= 0):
1604
+ cdf = np.concatenate(([0], cdf_data, [1]))
1605
+ lj = np.concatenate((lj, [1]))
1606
+ else:
1607
+ cdf = np.concatenate(([0], cdf_data))
1608
+ # here we could use logcdf w/ logsumexp trick to take differences,
1609
+ # but in the context of the method, it seems unlikely to matter
1610
+ return lj * np.log(np.diff(cdf) / lj)
1611
+
1612
+ return self._nlff_and_penalty(x, args, log_psf)
1613
+
1614
+
1615
+ class _ShapeInfo:
1616
+ def __init__(self, name, integrality=False, domain=(-np.inf, np.inf),
1617
+ inclusive=(True, True)):
1618
+ self.name = name
1619
+ self.integrality = integrality
1620
+ self.endpoints = domain
1621
+ self.inclusive = inclusive
1622
+
1623
+ domain = list(domain)
1624
+ if np.isfinite(domain[0]) and not inclusive[0]:
1625
+ domain[0] = np.nextafter(domain[0], np.inf)
1626
+ if np.isfinite(domain[1]) and not inclusive[1]:
1627
+ domain[1] = np.nextafter(domain[1], -np.inf)
1628
+ self.domain = domain
1629
+
1630
+
1631
+ def _get_fixed_fit_value(kwds, names):
1632
+ """
1633
+ Given names such as ``['f0', 'fa', 'fix_a']``, check that there is
1634
+ at most one non-None value in `kwds` associated with those names.
1635
+ Return that value, or None if none of the names occur in `kwds`.
1636
+ As a side effect, all occurrences of those names in `kwds` are
1637
+ removed.
1638
+ """
1639
+ vals = [(name, kwds.pop(name)) for name in names if name in kwds]
1640
+ if len(vals) > 1:
1641
+ repeated = [name for name, val in vals]
1642
+ raise ValueError("fit method got multiple keyword arguments to "
1643
+ "specify the same fixed parameter: " +
1644
+ ', '.join(repeated))
1645
+ return vals[0][1] if vals else None
1646
+
1647
+
1648
+ # continuous random variables: implement maybe later
1649
+ #
1650
+ # hf --- Hazard Function (PDF / SF)
1651
+ # chf --- Cumulative hazard function (-log(SF))
1652
+ # psf --- Probability sparsity function (reciprocal of the pdf) in
1653
+ # units of percent-point-function (as a function of q).
1654
+ # Also, the derivative of the percent-point function.
1655
+
1656
+
1657
+ class rv_continuous(rv_generic):
1658
+ """A generic continuous random variable class meant for subclassing.
1659
+
1660
+ `rv_continuous` is a base class to construct specific distribution classes
1661
+ and instances for continuous random variables. It cannot be used
1662
+ directly as a distribution.
1663
+
1664
+ Parameters
1665
+ ----------
1666
+ momtype : int, optional
1667
+ The type of generic moment calculation to use: 0 for pdf, 1 (default)
1668
+ for ppf.
1669
+ a : float, optional
1670
+ Lower bound of the support of the distribution, default is minus
1671
+ infinity.
1672
+ b : float, optional
1673
+ Upper bound of the support of the distribution, default is plus
1674
+ infinity.
1675
+ xtol : float, optional
1676
+ The tolerance for fixed point calculation for generic ppf.
1677
+ badvalue : float, optional
1678
+ The value in a result arrays that indicates a value that for which
1679
+ some argument restriction is violated, default is np.nan.
1680
+ name : str, optional
1681
+ The name of the instance. This string is used to construct the default
1682
+ example for distributions.
1683
+ longname : str, optional
1684
+ This string is used as part of the first line of the docstring returned
1685
+ when a subclass has no docstring of its own. Note: `longname` exists
1686
+ for backwards compatibility, do not use for new subclasses.
1687
+ shapes : str, optional
1688
+ The shape of the distribution. For example ``"m, n"`` for a
1689
+ distribution that takes two integers as the two shape arguments for all
1690
+ its methods. If not provided, shape parameters will be inferred from
1691
+ the signature of the private methods, ``_pdf`` and ``_cdf`` of the
1692
+ instance.
1693
+ seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
1694
+ If `seed` is None (or `np.random`), the `numpy.random.RandomState`
1695
+ singleton is used.
1696
+ If `seed` is an int, a new ``RandomState`` instance is used,
1697
+ seeded with `seed`.
1698
+ If `seed` is already a ``Generator`` or ``RandomState`` instance then
1699
+ that instance is used.
1700
+
1701
+ Attributes
1702
+ ----------
1703
+ a, b : float, optional
1704
+ Lower/upper bound of the support of the unshifted/unscaled distribution.
1705
+ This value is unaffected by the `loc` and `scale` parameters.
1706
+ To calculate the support of the shifted/scaled distribution,
1707
+ use the `support` method.
1708
+
1709
+ Methods
1710
+ -------
1711
+ rvs
1712
+ pdf
1713
+ logpdf
1714
+ cdf
1715
+ logcdf
1716
+ sf
1717
+ logsf
1718
+ ppf
1719
+ isf
1720
+ moment
1721
+ stats
1722
+ entropy
1723
+ expect
1724
+ median
1725
+ mean
1726
+ std
1727
+ var
1728
+ interval
1729
+ __call__
1730
+ fit
1731
+ fit_loc_scale
1732
+ nnlf
1733
+ support
1734
+
1735
+ Notes
1736
+ -----
1737
+ Public methods of an instance of a distribution class (e.g., ``pdf``,
1738
+ ``cdf``) check their arguments and pass valid arguments to private,
1739
+ computational methods (``_pdf``, ``_cdf``). For ``pdf(x)``, ``x`` is valid
1740
+ if it is within the support of the distribution.
1741
+ Whether a shape parameter is valid is decided by an ``_argcheck`` method
1742
+ (which defaults to checking that its arguments are strictly positive.)
1743
+
1744
+ **Subclassing**
1745
+
1746
+ New random variables can be defined by subclassing the `rv_continuous` class
1747
+ and re-defining at least the ``_pdf`` or the ``_cdf`` method (normalized
1748
+ to location 0 and scale 1).
1749
+
1750
+ If positive argument checking is not correct for your RV
1751
+ then you will also need to re-define the ``_argcheck`` method.
1752
+
1753
+ For most of the scipy.stats distributions, the support interval doesn't
1754
+ depend on the shape parameters. ``x`` being in the support interval is
1755
+ equivalent to ``self.a <= x <= self.b``. If either of the endpoints of
1756
+ the support do depend on the shape parameters, then
1757
+ i) the distribution must implement the ``_get_support`` method; and
1758
+ ii) those dependent endpoints must be omitted from the distribution's
1759
+ call to the ``rv_continuous`` initializer.
1760
+
1761
+ Correct, but potentially slow defaults exist for the remaining
1762
+ methods but for speed and/or accuracy you can over-ride::
1763
+
1764
+ _logpdf, _cdf, _logcdf, _ppf, _rvs, _isf, _sf, _logsf
1765
+
1766
+ The default method ``_rvs`` relies on the inverse of the cdf, ``_ppf``,
1767
+ applied to a uniform random variate. In order to generate random variates
1768
+ efficiently, either the default ``_ppf`` needs to be overwritten (e.g.
1769
+ if the inverse cdf can expressed in an explicit form) or a sampling
1770
+ method needs to be implemented in a custom ``_rvs`` method.
1771
+
1772
+ If possible, you should override ``_isf``, ``_sf`` or ``_logsf``.
1773
+ The main reason would be to improve numerical accuracy: for example,
1774
+ the survival function ``_sf`` is computed as ``1 - _cdf`` which can
1775
+ result in loss of precision if ``_cdf(x)`` is close to one.
1776
+
1777
+ **Methods that can be overwritten by subclasses**
1778
+ ::
1779
+
1780
+ _rvs
1781
+ _pdf
1782
+ _cdf
1783
+ _sf
1784
+ _ppf
1785
+ _isf
1786
+ _stats
1787
+ _munp
1788
+ _entropy
1789
+ _argcheck
1790
+ _get_support
1791
+
1792
+ There are additional (internal and private) generic methods that can
1793
+ be useful for cross-checking and for debugging, but might work in all
1794
+ cases when directly called.
1795
+
1796
+ A note on ``shapes``: subclasses need not specify them explicitly. In this
1797
+ case, `shapes` will be automatically deduced from the signatures of the
1798
+ overridden methods (`pdf`, `cdf` etc).
1799
+ If, for some reason, you prefer to avoid relying on introspection, you can
1800
+ specify ``shapes`` explicitly as an argument to the instance constructor.
1801
+
1802
+
1803
+ **Frozen Distributions**
1804
+
1805
+ Normally, you must provide shape parameters (and, optionally, location and
1806
+ scale parameters to each call of a method of a distribution.
1807
+
1808
+ Alternatively, the object may be called (as a function) to fix the shape,
1809
+ location, and scale parameters returning a "frozen" continuous RV object:
1810
+
1811
+ rv = generic(<shape(s)>, loc=0, scale=1)
1812
+ `rv_frozen` object with the same methods but holding the given shape,
1813
+ location, and scale fixed
1814
+
1815
+ **Statistics**
1816
+
1817
+ Statistics are computed using numerical integration by default.
1818
+ For speed you can redefine this using ``_stats``:
1819
+
1820
+ - take shape parameters and return mu, mu2, g1, g2
1821
+ - If you can't compute one of these, return it as None
1822
+ - Can also be defined with a keyword argument ``moments``, which is a
1823
+ string composed of "m", "v", "s", and/or "k".
1824
+ Only the components appearing in string should be computed and
1825
+ returned in the order "m", "v", "s", or "k" with missing values
1826
+ returned as None.
1827
+
1828
+ Alternatively, you can override ``_munp``, which takes ``n`` and shape
1829
+ parameters and returns the n-th non-central moment of the distribution.
1830
+
1831
+ **Deepcopying / Pickling**
1832
+
1833
+ If a distribution or frozen distribution is deepcopied (pickled/unpickled,
1834
+ etc.), any underlying random number generator is deepcopied with it. An
1835
+ implication is that if a distribution relies on the singleton RandomState
1836
+ before copying, it will rely on a copy of that random state after copying,
1837
+ and ``np.random.seed`` will no longer control the state.
1838
+
1839
+ Examples
1840
+ --------
1841
+ To create a new Gaussian distribution, we would do the following:
1842
+
1843
+ >>> from scipy.stats import rv_continuous
1844
+ >>> class gaussian_gen(rv_continuous):
1845
+ ... "Gaussian distribution"
1846
+ ... def _pdf(self, x):
1847
+ ... return np.exp(-x**2 / 2.) / np.sqrt(2.0 * np.pi)
1848
+ >>> gaussian = gaussian_gen(name='gaussian')
1849
+
1850
+ ``scipy.stats`` distributions are *instances*, so here we subclass
1851
+ `rv_continuous` and create an instance. With this, we now have
1852
+ a fully functional distribution with all relevant methods automagically
1853
+ generated by the framework.
1854
+
1855
+ Note that above we defined a standard normal distribution, with zero mean
1856
+ and unit variance. Shifting and scaling of the distribution can be done
1857
+ by using ``loc`` and ``scale`` parameters: ``gaussian.pdf(x, loc, scale)``
1858
+ essentially computes ``y = (x - loc) / scale`` and
1859
+ ``gaussian._pdf(y) / scale``.
1860
+
1861
+ """
1862
+
1863
+ def __init__(self, momtype=1, a=None, b=None, xtol=1e-14,
1864
+ badvalue=None, name=None, longname=None,
1865
+ shapes=None, seed=None):
1866
+
1867
+ super().__init__(seed)
1868
+
1869
+ # save the ctor parameters, cf generic freeze
1870
+ self._ctor_param = dict(
1871
+ momtype=momtype, a=a, b=b, xtol=xtol,
1872
+ badvalue=badvalue, name=name, longname=longname,
1873
+ shapes=shapes, seed=seed)
1874
+
1875
+ if badvalue is None:
1876
+ badvalue = nan
1877
+ if name is None:
1878
+ name = 'Distribution'
1879
+ self.badvalue = badvalue
1880
+ self.name = name
1881
+ self.a = a
1882
+ self.b = b
1883
+ if a is None:
1884
+ self.a = -inf
1885
+ if b is None:
1886
+ self.b = inf
1887
+ self.xtol = xtol
1888
+ self.moment_type = momtype
1889
+ self.shapes = shapes
1890
+
1891
+ self._construct_argparser(meths_to_inspect=[self._pdf, self._cdf],
1892
+ locscale_in='loc=0, scale=1',
1893
+ locscale_out='loc, scale')
1894
+ self._attach_methods()
1895
+
1896
+ if longname is None:
1897
+ if name[0] in ['aeiouAEIOU']:
1898
+ hstr = "An "
1899
+ else:
1900
+ hstr = "A "
1901
+ longname = hstr + name
1902
+
1903
+ if sys.flags.optimize < 2:
1904
+ # Skip adding docstrings if interpreter is run with -OO
1905
+ if self.__doc__ is None:
1906
+ self._construct_default_doc(longname=longname,
1907
+ docdict=docdict,
1908
+ discrete='continuous')
1909
+ else:
1910
+ dct = dict(distcont)
1911
+ self._construct_doc(docdict, dct.get(self.name))
1912
+
1913
+ def __getstate__(self):
1914
+ dct = self.__dict__.copy()
1915
+
1916
+ # these methods will be remade in __setstate__
1917
+ # _random_state attribute is taken care of by rv_generic
1918
+ attrs = ["_parse_args", "_parse_args_stats", "_parse_args_rvs",
1919
+ "_cdfvec", "_ppfvec", "vecentropy", "generic_moment"]
1920
+ [dct.pop(attr, None) for attr in attrs]
1921
+ return dct
1922
+
1923
+ def _attach_methods(self):
1924
+ """
1925
+ Attaches dynamically created methods to the rv_continuous instance.
1926
+ """
1927
+ # _attach_methods is responsible for calling _attach_argparser_methods
1928
+ self._attach_argparser_methods()
1929
+
1930
+ # nin correction
1931
+ self._ppfvec = vectorize(self._ppf_single, otypes='d')
1932
+ self._ppfvec.nin = self.numargs + 1
1933
+ self.vecentropy = vectorize(self._entropy, otypes='d')
1934
+ self._cdfvec = vectorize(self._cdf_single, otypes='d')
1935
+ self._cdfvec.nin = self.numargs + 1
1936
+
1937
+ if self.moment_type == 0:
1938
+ self.generic_moment = vectorize(self._mom0_sc, otypes='d')
1939
+ else:
1940
+ self.generic_moment = vectorize(self._mom1_sc, otypes='d')
1941
+ # Because of the *args argument of _mom0_sc, vectorize cannot count the
1942
+ # number of arguments correctly.
1943
+ self.generic_moment.nin = self.numargs + 1
1944
+
1945
+ def _updated_ctor_param(self):
1946
+ """Return the current version of _ctor_param, possibly updated by user.
1947
+
1948
+ Used by freezing.
1949
+ Keep this in sync with the signature of __init__.
1950
+ """
1951
+ dct = self._ctor_param.copy()
1952
+ dct['a'] = self.a
1953
+ dct['b'] = self.b
1954
+ dct['xtol'] = self.xtol
1955
+ dct['badvalue'] = self.badvalue
1956
+ dct['name'] = self.name
1957
+ dct['shapes'] = self.shapes
1958
+ return dct
1959
+
1960
+ def _ppf_to_solve(self, x, q, *args):
1961
+ return self.cdf(*(x, )+args)-q
1962
+
1963
+ def _ppf_single(self, q, *args):
1964
+ factor = 10.
1965
+ left, right = self._get_support(*args)
1966
+
1967
+ if np.isinf(left):
1968
+ left = min(-factor, right)
1969
+ while self._ppf_to_solve(left, q, *args) > 0.:
1970
+ left, right = left * factor, left
1971
+ # left is now such that cdf(left) <= q
1972
+ # if right has changed, then cdf(right) > q
1973
+
1974
+ if np.isinf(right):
1975
+ right = max(factor, left)
1976
+ while self._ppf_to_solve(right, q, *args) < 0.:
1977
+ left, right = right, right * factor
1978
+ # right is now such that cdf(right) >= q
1979
+
1980
+ return optimize.brentq(self._ppf_to_solve,
1981
+ left, right, args=(q,)+args, xtol=self.xtol)
1982
+
1983
+ # moment from definition
1984
+ def _mom_integ0(self, x, m, *args):
1985
+ return x**m * self.pdf(x, *args)
1986
+
1987
+ def _mom0_sc(self, m, *args):
1988
+ _a, _b = self._get_support(*args)
1989
+ return integrate.quad(self._mom_integ0, _a, _b,
1990
+ args=(m,)+args)[0]
1991
+
1992
+ # moment calculated using ppf
1993
+ def _mom_integ1(self, q, m, *args):
1994
+ return (self.ppf(q, *args))**m
1995
+
1996
+ def _mom1_sc(self, m, *args):
1997
+ return integrate.quad(self._mom_integ1, 0, 1, args=(m,)+args)[0]
1998
+
1999
+ def _pdf(self, x, *args):
2000
+ return _derivative(self._cdf, x, dx=1e-5, args=args, order=5)
2001
+
2002
+ # Could also define any of these
2003
+ def _logpdf(self, x, *args):
2004
+ p = self._pdf(x, *args)
2005
+ with np.errstate(divide='ignore'):
2006
+ return log(p)
2007
+
2008
+ def _logpxf(self, x, *args):
2009
+ # continuous distributions have PDF, discrete have PMF, but sometimes
2010
+ # the distinction doesn't matter. This lets us use `_logpxf` for both
2011
+ # discrete and continuous distributions.
2012
+ return self._logpdf(x, *args)
2013
+
2014
+ def _cdf_single(self, x, *args):
2015
+ _a, _b = self._get_support(*args)
2016
+ return integrate.quad(self._pdf, _a, x, args=args)[0]
2017
+
2018
+ def _cdf(self, x, *args):
2019
+ return self._cdfvec(x, *args)
2020
+
2021
+ def _logcdf(self, x, *args):
2022
+ median = self._ppf(0.5, *args)
2023
+ with np.errstate(divide='ignore'):
2024
+ return xpx.apply_where(
2025
+ x < median, (x,) + args,
2026
+ lambda x, *args: np.log(self._cdf(x, *args)),
2027
+ lambda x, *args: np.log1p(-self._sf(x, *args)))
2028
+
2029
+ def _logsf(self, x, *args):
2030
+ median = self._ppf(0.5, *args)
2031
+ with np.errstate(divide='ignore'):
2032
+ return xpx.apply_where(
2033
+ x > median, (x,) + args,
2034
+ lambda x, *args: np.log(self._sf(x, *args)),
2035
+ lambda x, *args: np.log1p(-self._cdf(x, *args)))
2036
+
2037
+ # generic _argcheck, _sf, _ppf, _isf, _rvs are defined
2038
+ # in rv_generic
2039
+
2040
+ def pdf(self, x, *args, **kwds):
2041
+ """Probability density function at x of the given RV.
2042
+
2043
+ Parameters
2044
+ ----------
2045
+ x : array_like
2046
+ quantiles
2047
+ arg1, arg2, arg3,... : array_like
2048
+ The shape parameter(s) for the distribution (see docstring of the
2049
+ instance object for more information)
2050
+ loc : array_like, optional
2051
+ location parameter (default=0)
2052
+ scale : array_like, optional
2053
+ scale parameter (default=1)
2054
+
2055
+ Returns
2056
+ -------
2057
+ pdf : ndarray
2058
+ Probability density function evaluated at x
2059
+
2060
+ """
2061
+ args, loc, scale = self._parse_args(*args, **kwds)
2062
+ x, loc, scale = map(asarray, (x, loc, scale))
2063
+ args = tuple(map(asarray, args))
2064
+ dtyp = np.promote_types(x.dtype, np.float64)
2065
+ x = np.asarray((x - loc)/scale, dtype=dtyp)
2066
+ cond0 = self._argcheck(*args) & (scale > 0)
2067
+ cond1 = self._support_mask(x, *args) & (scale > 0)
2068
+ cond = cond0 & cond1
2069
+ output = zeros(shape(cond), dtyp)
2070
+ putmask(output, (1-cond0)+np.isnan(x), self.badvalue)
2071
+ if np.any(cond):
2072
+ goodargs = argsreduce(cond, *((x,)+args+(scale,)))
2073
+ scale, goodargs = goodargs[-1], goodargs[:-1]
2074
+ place(output, cond, self._pdf(*goodargs) / scale)
2075
+ if output.ndim == 0:
2076
+ return output[()]
2077
+ return output
2078
+
2079
+ def logpdf(self, x, *args, **kwds):
2080
+ """Log of the probability density function at x of the given RV.
2081
+
2082
+ This uses a more numerically accurate calculation if available.
2083
+
2084
+ Parameters
2085
+ ----------
2086
+ x : array_like
2087
+ quantiles
2088
+ arg1, arg2, arg3,... : array_like
2089
+ The shape parameter(s) for the distribution (see docstring of the
2090
+ instance object for more information)
2091
+ loc : array_like, optional
2092
+ location parameter (default=0)
2093
+ scale : array_like, optional
2094
+ scale parameter (default=1)
2095
+
2096
+ Returns
2097
+ -------
2098
+ logpdf : array_like
2099
+ Log of the probability density function evaluated at x
2100
+
2101
+ """
2102
+ args, loc, scale = self._parse_args(*args, **kwds)
2103
+ x, loc, scale = map(asarray, (x, loc, scale))
2104
+ args = tuple(map(asarray, args))
2105
+ dtyp = np.promote_types(x.dtype, np.float64)
2106
+ x = np.asarray((x - loc)/scale, dtype=dtyp)
2107
+ cond0 = self._argcheck(*args) & (scale > 0)
2108
+ cond1 = self._support_mask(x, *args) & (scale > 0)
2109
+ cond = cond0 & cond1
2110
+ output = empty(shape(cond), dtyp)
2111
+ output.fill(-inf)
2112
+ putmask(output, (1-cond0)+np.isnan(x), self.badvalue)
2113
+ if np.any(cond):
2114
+ goodargs = argsreduce(cond, *((x,)+args+(scale,)))
2115
+ scale, goodargs = goodargs[-1], goodargs[:-1]
2116
+ place(output, cond, self._logpdf(*goodargs) - log(scale))
2117
+ if output.ndim == 0:
2118
+ return output[()]
2119
+ return output
2120
+
2121
+ def cdf(self, x, *args, **kwds):
2122
+ """
2123
+ Cumulative distribution function of the given RV.
2124
+
2125
+ Parameters
2126
+ ----------
2127
+ x : array_like
2128
+ quantiles
2129
+ arg1, arg2, arg3,... : array_like
2130
+ The shape parameter(s) for the distribution (see docstring of the
2131
+ instance object for more information)
2132
+ loc : array_like, optional
2133
+ location parameter (default=0)
2134
+ scale : array_like, optional
2135
+ scale parameter (default=1)
2136
+
2137
+ Returns
2138
+ -------
2139
+ cdf : ndarray
2140
+ Cumulative distribution function evaluated at `x`
2141
+
2142
+ """
2143
+ args, loc, scale = self._parse_args(*args, **kwds)
2144
+ x, loc, scale = map(asarray, (x, loc, scale))
2145
+ args = tuple(map(asarray, args))
2146
+ _a, _b = self._get_support(*args)
2147
+ dtyp = np.promote_types(x.dtype, np.float64)
2148
+ x = np.asarray((x - loc)/scale, dtype=dtyp)
2149
+ cond0 = self._argcheck(*args) & (scale > 0)
2150
+ cond1 = self._open_support_mask(x, *args) & (scale > 0)
2151
+ cond2 = (x >= np.asarray(_b)) & cond0
2152
+ cond = cond0 & cond1
2153
+ output = zeros(shape(cond), dtyp)
2154
+ place(output, (1-cond0)+np.isnan(x), self.badvalue)
2155
+ place(output, cond2, 1.0)
2156
+ if np.any(cond): # call only if at least 1 entry
2157
+ goodargs = argsreduce(cond, *((x,)+args))
2158
+ place(output, cond, self._cdf(*goodargs))
2159
+ if output.ndim == 0:
2160
+ return output[()]
2161
+ return output
2162
+
2163
+ def logcdf(self, x, *args, **kwds):
2164
+ """Log of the cumulative distribution function at x of the given RV.
2165
+
2166
+ Parameters
2167
+ ----------
2168
+ x : array_like
2169
+ quantiles
2170
+ arg1, arg2, arg3,... : array_like
2171
+ The shape parameter(s) for the distribution (see docstring of the
2172
+ instance object for more information)
2173
+ loc : array_like, optional
2174
+ location parameter (default=0)
2175
+ scale : array_like, optional
2176
+ scale parameter (default=1)
2177
+
2178
+ Returns
2179
+ -------
2180
+ logcdf : array_like
2181
+ Log of the cumulative distribution function evaluated at x
2182
+
2183
+ """
2184
+ args, loc, scale = self._parse_args(*args, **kwds)
2185
+ x, loc, scale = map(asarray, (x, loc, scale))
2186
+ args = tuple(map(asarray, args))
2187
+ _a, _b = self._get_support(*args)
2188
+ dtyp = np.promote_types(x.dtype, np.float64)
2189
+ x = np.asarray((x - loc)/scale, dtype=dtyp)
2190
+ cond0 = self._argcheck(*args) & (scale > 0)
2191
+ cond1 = self._open_support_mask(x, *args) & (scale > 0)
2192
+ cond2 = (x >= _b) & cond0
2193
+ cond = cond0 & cond1
2194
+ output = empty(shape(cond), dtyp)
2195
+ output.fill(-inf)
2196
+ place(output, (1-cond0)*(cond1 == cond1)+np.isnan(x), self.badvalue)
2197
+ place(output, cond2, 0.0)
2198
+ if np.any(cond): # call only if at least 1 entry
2199
+ goodargs = argsreduce(cond, *((x,)+args))
2200
+ place(output, cond, self._logcdf(*goodargs))
2201
+ if output.ndim == 0:
2202
+ return output[()]
2203
+ return output
2204
+
2205
+ def sf(self, x, *args, **kwds):
2206
+ """Survival function (1 - `cdf`) at x of the given RV.
2207
+
2208
+ Parameters
2209
+ ----------
2210
+ x : array_like
2211
+ quantiles
2212
+ arg1, arg2, arg3,... : array_like
2213
+ The shape parameter(s) for the distribution (see docstring of the
2214
+ instance object for more information)
2215
+ loc : array_like, optional
2216
+ location parameter (default=0)
2217
+ scale : array_like, optional
2218
+ scale parameter (default=1)
2219
+
2220
+ Returns
2221
+ -------
2222
+ sf : array_like
2223
+ Survival function evaluated at x
2224
+
2225
+ """
2226
+ args, loc, scale = self._parse_args(*args, **kwds)
2227
+ x, loc, scale = map(asarray, (x, loc, scale))
2228
+ args = tuple(map(asarray, args))
2229
+ _a, _b = self._get_support(*args)
2230
+ dtyp = np.promote_types(x.dtype, np.float64)
2231
+ x = np.asarray((x - loc)/scale, dtype=dtyp)
2232
+ cond0 = self._argcheck(*args) & (scale > 0)
2233
+ cond1 = self._open_support_mask(x, *args) & (scale > 0)
2234
+ cond2 = cond0 & (x <= _a)
2235
+ cond = cond0 & cond1
2236
+ output = zeros(shape(cond), dtyp)
2237
+ place(output, (1-cond0)+np.isnan(x), self.badvalue)
2238
+ place(output, cond2, 1.0)
2239
+ if np.any(cond):
2240
+ goodargs = argsreduce(cond, *((x,)+args))
2241
+ place(output, cond, self._sf(*goodargs))
2242
+ if output.ndim == 0:
2243
+ return output[()]
2244
+ return output
2245
+
2246
+ def logsf(self, x, *args, **kwds):
2247
+ """Log of the survival function of the given RV.
2248
+
2249
+ Returns the log of the "survival function," defined as (1 - `cdf`),
2250
+ evaluated at `x`.
2251
+
2252
+ Parameters
2253
+ ----------
2254
+ x : array_like
2255
+ quantiles
2256
+ arg1, arg2, arg3,... : array_like
2257
+ The shape parameter(s) for the distribution (see docstring of the
2258
+ instance object for more information)
2259
+ loc : array_like, optional
2260
+ location parameter (default=0)
2261
+ scale : array_like, optional
2262
+ scale parameter (default=1)
2263
+
2264
+ Returns
2265
+ -------
2266
+ logsf : ndarray
2267
+ Log of the survival function evaluated at `x`.
2268
+
2269
+ """
2270
+ args, loc, scale = self._parse_args(*args, **kwds)
2271
+ x, loc, scale = map(asarray, (x, loc, scale))
2272
+ args = tuple(map(asarray, args))
2273
+ _a, _b = self._get_support(*args)
2274
+ dtyp = np.promote_types(x.dtype, np.float64)
2275
+ x = np.asarray((x - loc)/scale, dtype=dtyp)
2276
+ cond0 = self._argcheck(*args) & (scale > 0)
2277
+ cond1 = self._open_support_mask(x, *args) & (scale > 0)
2278
+ cond2 = cond0 & (x <= _a)
2279
+ cond = cond0 & cond1
2280
+ output = empty(shape(cond), dtyp)
2281
+ output.fill(-inf)
2282
+ place(output, (1-cond0)+np.isnan(x), self.badvalue)
2283
+ place(output, cond2, 0.0)
2284
+ if np.any(cond):
2285
+ goodargs = argsreduce(cond, *((x,)+args))
2286
+ place(output, cond, self._logsf(*goodargs))
2287
+ if output.ndim == 0:
2288
+ return output[()]
2289
+ return output
2290
+
2291
+ def ppf(self, q, *args, **kwds):
2292
+ """Percent point function (inverse of `cdf`) at q of the given RV.
2293
+
2294
+ Parameters
2295
+ ----------
2296
+ q : array_like
2297
+ lower tail probability
2298
+ arg1, arg2, arg3,... : array_like
2299
+ The shape parameter(s) for the distribution (see docstring of the
2300
+ instance object for more information)
2301
+ loc : array_like, optional
2302
+ location parameter (default=0)
2303
+ scale : array_like, optional
2304
+ scale parameter (default=1)
2305
+
2306
+ Returns
2307
+ -------
2308
+ x : array_like
2309
+ quantile corresponding to the lower tail probability q.
2310
+
2311
+ """
2312
+ args, loc, scale = self._parse_args(*args, **kwds)
2313
+ q, loc, scale = map(asarray, (q, loc, scale))
2314
+ args = tuple(map(asarray, args))
2315
+ _a, _b = self._get_support(*args)
2316
+ cond0 = self._argcheck(*args) & (scale > 0) & (loc == loc)
2317
+ cond1 = (0 < q) & (q < 1)
2318
+ cond2 = cond0 & (q == 0)
2319
+ cond3 = cond0 & (q == 1)
2320
+ cond = cond0 & cond1
2321
+ output = np.full(shape(cond), fill_value=self.badvalue)
2322
+
2323
+ lower_bound = _a * scale + loc
2324
+ upper_bound = _b * scale + loc
2325
+ place(output, cond2, argsreduce(cond2, lower_bound)[0])
2326
+ place(output, cond3, argsreduce(cond3, upper_bound)[0])
2327
+
2328
+ if np.any(cond): # call only if at least 1 entry
2329
+ goodargs = argsreduce(cond, *((q,)+args+(scale, loc)))
2330
+ scale, loc, goodargs = goodargs[-2], goodargs[-1], goodargs[:-2]
2331
+ place(output, cond, self._ppf(*goodargs) * scale + loc)
2332
+ if output.ndim == 0:
2333
+ return output[()]
2334
+ return output
2335
+
2336
+ def isf(self, q, *args, **kwds):
2337
+ """Inverse survival function (inverse of `sf`) at q of the given RV.
2338
+
2339
+ Parameters
2340
+ ----------
2341
+ q : array_like
2342
+ upper tail probability
2343
+ arg1, arg2, arg3,... : array_like
2344
+ The shape parameter(s) for the distribution (see docstring of the
2345
+ instance object for more information)
2346
+ loc : array_like, optional
2347
+ location parameter (default=0)
2348
+ scale : array_like, optional
2349
+ scale parameter (default=1)
2350
+
2351
+ Returns
2352
+ -------
2353
+ x : ndarray or scalar
2354
+ Quantile corresponding to the upper tail probability q.
2355
+
2356
+ """
2357
+ args, loc, scale = self._parse_args(*args, **kwds)
2358
+ q, loc, scale = map(asarray, (q, loc, scale))
2359
+ args = tuple(map(asarray, args))
2360
+ _a, _b = self._get_support(*args)
2361
+ cond0 = self._argcheck(*args) & (scale > 0) & (loc == loc)
2362
+ cond1 = (0 < q) & (q < 1)
2363
+ cond2 = cond0 & (q == 1)
2364
+ cond3 = cond0 & (q == 0)
2365
+ cond = cond0 & cond1
2366
+ output = np.full(shape(cond), fill_value=self.badvalue)
2367
+
2368
+ lower_bound = _a * scale + loc
2369
+ upper_bound = _b * scale + loc
2370
+ place(output, cond2, argsreduce(cond2, lower_bound)[0])
2371
+ place(output, cond3, argsreduce(cond3, upper_bound)[0])
2372
+
2373
+ if np.any(cond):
2374
+ goodargs = argsreduce(cond, *((q,)+args+(scale, loc)))
2375
+ scale, loc, goodargs = goodargs[-2], goodargs[-1], goodargs[:-2]
2376
+ place(output, cond, self._isf(*goodargs) * scale + loc)
2377
+ if output.ndim == 0:
2378
+ return output[()]
2379
+ return output
2380
+
2381
+ def _unpack_loc_scale(self, theta):
2382
+ try:
2383
+ loc = theta[-2]
2384
+ scale = theta[-1]
2385
+ args = tuple(theta[:-2])
2386
+ except IndexError as e:
2387
+ raise ValueError("Not enough input arguments.") from e
2388
+ return loc, scale, args
2389
+
2390
+ def _nnlf_and_penalty(self, x, args):
2391
+ """
2392
+ Compute the penalized negative log-likelihood for the
2393
+ "standardized" data (i.e. already shifted by loc and
2394
+ scaled by scale) for the shape parameters in `args`.
2395
+
2396
+ `x` can be a 1D numpy array or a CensoredData instance.
2397
+ """
2398
+ if isinstance(x, CensoredData):
2399
+ # Filter out the data that is not in the support.
2400
+ xs = x._supported(*self._get_support(*args))
2401
+ n_bad = len(x) - len(xs)
2402
+ i1, i2 = xs._interval.T
2403
+ terms = [
2404
+ # logpdf of the noncensored data.
2405
+ self._logpdf(xs._uncensored, *args),
2406
+ # logcdf of the left-censored data.
2407
+ self._logcdf(xs._left, *args),
2408
+ # logsf of the right-censored data.
2409
+ self._logsf(xs._right, *args),
2410
+ # log of probability of the interval-censored data.
2411
+ np.log(self._delta_cdf(i1, i2, *args)),
2412
+ ]
2413
+ else:
2414
+ cond0 = ~self._support_mask(x, *args)
2415
+ n_bad = np.count_nonzero(cond0)
2416
+ if n_bad > 0:
2417
+ x = argsreduce(~cond0, x)[0]
2418
+ terms = [self._logpdf(x, *args)]
2419
+
2420
+ totals, bad_counts = zip(*[_sum_finite(term) for term in terms])
2421
+ total = sum(totals)
2422
+ n_bad += sum(bad_counts)
2423
+
2424
+ return -total + n_bad * _LOGXMAX * 100
2425
+
2426
+ def _penalized_nnlf(self, theta, x):
2427
+ """Penalized negative loglikelihood function.
2428
+
2429
+ i.e., - sum (log pdf(x, theta), axis=0) + penalty
2430
+ where theta are the parameters (including loc and scale)
2431
+ """
2432
+ loc, scale, args = self._unpack_loc_scale(theta)
2433
+ if not self._argcheck(*args) or scale <= 0:
2434
+ return inf
2435
+ if isinstance(x, CensoredData):
2436
+ x = (x - loc) / scale
2437
+ n_log_scale = (len(x) - x.num_censored()) * log(scale)
2438
+ else:
2439
+ x = (x - loc) / scale
2440
+ n_log_scale = len(x) * log(scale)
2441
+
2442
+ return self._nnlf_and_penalty(x, args) + n_log_scale
2443
+
2444
+ def _fitstart(self, data, args=None):
2445
+ """Starting point for fit (shape arguments + loc + scale)."""
2446
+ if args is None:
2447
+ args = (1.0,)*self.numargs
2448
+ loc, scale = self._fit_loc_scale_support(data, *args)
2449
+ return args + (loc, scale)
2450
+
2451
+ def _reduce_func(self, args, kwds, data=None):
2452
+ """
2453
+ Return the (possibly reduced) function to optimize in order to find MLE
2454
+ estimates for the .fit method.
2455
+ """
2456
+ # Convert fixed shape parameters to the standard numeric form: e.g. for
2457
+ # stats.beta, shapes='a, b'. To fix `a`, the caller can give a value
2458
+ # for `f0`, `fa` or 'fix_a'. The following converts the latter two
2459
+ # into the first (numeric) form.
2460
+ shapes = []
2461
+ if self.shapes:
2462
+ shapes = self.shapes.replace(',', ' ').split()
2463
+ for j, s in enumerate(shapes):
2464
+ key = 'f' + str(j)
2465
+ names = [key, 'f' + s, 'fix_' + s]
2466
+ val = _get_fixed_fit_value(kwds, names)
2467
+ if val is not None:
2468
+ kwds[key] = val
2469
+
2470
+ args = list(args)
2471
+ Nargs = len(args)
2472
+ fixedn = []
2473
+ names = [f'f{n}' for n in range(Nargs - 2)] + ['floc', 'fscale']
2474
+ x0 = []
2475
+ for n, key in enumerate(names):
2476
+ if key in kwds:
2477
+ fixedn.append(n)
2478
+ args[n] = kwds.pop(key)
2479
+ else:
2480
+ x0.append(args[n])
2481
+
2482
+ methods = {"mle", "mm"}
2483
+ method = kwds.pop('method', "mle").lower()
2484
+ if method == "mm":
2485
+ n_params = len(shapes) + 2 - len(fixedn)
2486
+ exponents = (np.arange(1, n_params+1))[:, np.newaxis]
2487
+ data_moments = np.sum(data[None, :]**exponents/len(data), axis=1)
2488
+
2489
+ def objective(theta, x):
2490
+ return self._moment_error(theta, x, data_moments)
2491
+
2492
+ elif method == "mle":
2493
+ objective = self._penalized_nnlf
2494
+ else:
2495
+ raise ValueError(f"Method '{method}' not available; "
2496
+ f"must be one of {methods}")
2497
+
2498
+ if len(fixedn) == 0:
2499
+ func = objective
2500
+ restore = None
2501
+ else:
2502
+ if len(fixedn) == Nargs:
2503
+ raise ValueError(
2504
+ "All parameters fixed. There is nothing to optimize.")
2505
+
2506
+ def restore(args, theta):
2507
+ # Replace with theta for all numbers not in fixedn
2508
+ # This allows the non-fixed values to vary, but
2509
+ # we still call self.nnlf with all parameters.
2510
+ i = 0
2511
+ for n in range(Nargs):
2512
+ if n not in fixedn:
2513
+ args[n] = theta[i]
2514
+ i += 1
2515
+ return args
2516
+
2517
+ def func(theta, x):
2518
+ newtheta = restore(args[:], theta)
2519
+ return objective(newtheta, x)
2520
+
2521
+ return x0, func, restore, args
2522
+
2523
+ def _moment_error(self, theta, x, data_moments):
2524
+ loc, scale, args = self._unpack_loc_scale(theta)
2525
+ if not self._argcheck(*args) or scale <= 0:
2526
+ return inf
2527
+
2528
+ dist_moments = np.array([self.moment(i+1, *args, loc=loc, scale=scale)
2529
+ for i in range(len(data_moments))])
2530
+ if np.any(np.isnan(dist_moments)):
2531
+ raise ValueError("Method of moments encountered a non-finite "
2532
+ "distribution moment and cannot continue. "
2533
+ "Consider trying method='MLE'.")
2534
+
2535
+ return (((data_moments - dist_moments) /
2536
+ np.maximum(np.abs(data_moments), 1e-8))**2).sum()
2537
+
2538
+ def fit(self, data, *args, **kwds):
2539
+ r"""
2540
+ Return estimates of shape (if applicable), location, and scale
2541
+ parameters from data. The default estimation method is Maximum
2542
+ Likelihood Estimation (MLE), but Method of Moments (MM)
2543
+ is also available.
2544
+
2545
+ Starting estimates for the fit are given by input arguments;
2546
+ for any arguments not provided with starting estimates,
2547
+ ``self._fitstart(data)`` is called to generate such.
2548
+
2549
+ One can hold some parameters fixed to specific values by passing in
2550
+ keyword arguments ``f0``, ``f1``, ..., ``fn`` (for shape parameters)
2551
+ and ``floc`` and ``fscale`` (for location and scale parameters,
2552
+ respectively).
2553
+
2554
+ Parameters
2555
+ ----------
2556
+ data : array_like or `CensoredData` instance
2557
+ Data to use in estimating the distribution parameters.
2558
+ arg1, arg2, arg3,... : floats, optional
2559
+ Starting value(s) for any shape-characterizing arguments (those not
2560
+ provided will be determined by a call to ``_fitstart(data)``).
2561
+ No default value.
2562
+ **kwds : floats, optional
2563
+ - `loc`: initial guess of the distribution's location parameter.
2564
+ - `scale`: initial guess of the distribution's scale parameter.
2565
+
2566
+ Special keyword arguments are recognized as holding certain
2567
+ parameters fixed:
2568
+
2569
+ - f0...fn : hold respective shape parameters fixed.
2570
+ Alternatively, shape parameters to fix can be specified by name.
2571
+ For example, if ``self.shapes == "a, b"``, ``fa`` and ``fix_a``
2572
+ are equivalent to ``f0``, and ``fb`` and ``fix_b`` are
2573
+ equivalent to ``f1``.
2574
+
2575
+ - floc : hold location parameter fixed to specified value.
2576
+
2577
+ - fscale : hold scale parameter fixed to specified value.
2578
+
2579
+ - optimizer : The optimizer to use. The optimizer must take
2580
+ ``func`` and starting position as the first two arguments,
2581
+ plus ``args`` (for extra arguments to pass to the
2582
+ function to be optimized) and ``disp``.
2583
+ The ``fit`` method calls the optimizer with ``disp=0`` to suppress output.
2584
+ The optimizer must return the estimated parameters.
2585
+
2586
+ - method : The method to use. The default is "MLE" (Maximum
2587
+ Likelihood Estimate); "MM" (Method of Moments)
2588
+ is also available.
2589
+
2590
+ Raises
2591
+ ------
2592
+ TypeError, ValueError
2593
+ If an input is invalid
2594
+ `~scipy.stats.FitError`
2595
+ If fitting fails or the fit produced would be invalid
2596
+
2597
+ Returns
2598
+ -------
2599
+ parameter_tuple : tuple of floats
2600
+ Estimates for any shape parameters (if applicable), followed by
2601
+ those for location and scale. For most random variables, shape
2602
+ statistics will be returned, but there are exceptions (e.g.
2603
+ ``norm``).
2604
+
2605
+ Notes
2606
+ -----
2607
+ With ``method="MLE"`` (default), the fit is computed by minimizing
2608
+ the negative log-likelihood function. A large, finite penalty
2609
+ (rather than infinite negative log-likelihood) is applied for
2610
+ observations beyond the support of the distribution.
2611
+
2612
+ With ``method="MM"``, the fit is computed by minimizing the L2 norm
2613
+ of the relative errors between the first *k* raw (about zero) data
2614
+ moments and the corresponding distribution moments, where *k* is the
2615
+ number of non-fixed parameters.
2616
+ More precisely, the objective function is::
2617
+
2618
+ (((data_moments - dist_moments)
2619
+ / np.maximum(np.abs(data_moments), 1e-8))**2).sum()
2620
+
2621
+ where the constant ``1e-8`` avoids division by zero in case of
2622
+ vanishing data moments. Typically, this error norm can be reduced to
2623
+ zero.
2624
+ Note that the standard method of moments can produce parameters for
2625
+ which some data are outside the support of the fitted distribution;
2626
+ this implementation does nothing to prevent this.
2627
+
2628
+ For either method,
2629
+ the returned answer is not guaranteed to be globally optimal; it
2630
+ may only be locally optimal, or the optimization may fail altogether.
2631
+ If the data contain any of ``np.nan``, ``np.inf``, or ``-np.inf``,
2632
+ the `fit` method will raise a ``RuntimeError``.
2633
+
2634
+ When passing a ``CensoredData`` instance to ``data``, the log-likelihood
2635
+ function is defined as:
2636
+
2637
+ .. math::
2638
+
2639
+ l(\pmb{\theta}; k) & = \sum
2640
+ \log(f(k_u; \pmb{\theta}))
2641
+ + \sum
2642
+ \log(F(k_l; \pmb{\theta})) \\
2643
+ & + \sum
2644
+ \log(1 - F(k_r; \pmb{\theta})) \\
2645
+ & + \sum
2646
+ \log(F(k_{\text{high}, i}; \pmb{\theta})
2647
+ - F(k_{\text{low}, i}; \pmb{\theta}))
2648
+
2649
+ where :math:`f` and :math:`F` are the pdf and cdf, respectively, of the
2650
+ function being fitted, :math:`\pmb{\theta}` is the parameter vector,
2651
+ :math:`u` are the indices of uncensored observations,
2652
+ :math:`l` are the indices of left-censored observations,
2653
+ :math:`r` are the indices of right-censored observations,
2654
+ subscripts "low"/"high" denote endpoints of interval-censored observations, and
2655
+ :math:`i` are the indices of interval-censored observations.
2656
+
2657
+ Examples
2658
+ --------
2659
+
2660
+ Generate some data to fit: draw random variates from the `beta`
2661
+ distribution
2662
+
2663
+ >>> import numpy as np
2664
+ >>> from scipy.stats import beta
2665
+ >>> a, b = 1., 2.
2666
+ >>> rng = np.random.default_rng(172786373191770012695001057628748821561)
2667
+ >>> x = beta.rvs(a, b, size=1000, random_state=rng)
2668
+
2669
+ Now we can fit all four parameters (``a``, ``b``, ``loc`` and
2670
+ ``scale``):
2671
+
2672
+ >>> a1, b1, loc1, scale1 = beta.fit(x)
2673
+ >>> a1, b1, loc1, scale1
2674
+ (1.0198945204435628, 1.9484708982737828, 4.372241314917588e-05, 0.9979078845964814)
2675
+
2676
+ The fit can be done also using a custom optimizer:
2677
+
2678
+ >>> from scipy.optimize import minimize
2679
+ >>> def custom_optimizer(func, x0, args=(), disp=0):
2680
+ ... res = minimize(func, x0, args, method="slsqp", options={"disp": disp})
2681
+ ... if res.success:
2682
+ ... return res.x
2683
+ ... raise RuntimeError('optimization routine failed')
2684
+ >>> a1, b1, loc1, scale1 = beta.fit(x, method="MLE", optimizer=custom_optimizer)
2685
+ >>> a1, b1, loc1, scale1
2686
+ (1.0198821087258905, 1.948484145914738, 4.3705304486881485e-05, 0.9979104663953395)
2687
+
2688
+ We can also use some prior knowledge about the dataset: let's keep
2689
+ ``loc`` and ``scale`` fixed:
2690
+
2691
+ >>> a1, b1, loc1, scale1 = beta.fit(x, floc=0, fscale=1)
2692
+ >>> loc1, scale1
2693
+ (0, 1)
2694
+
2695
+ We can also keep shape parameters fixed by using ``f``-keywords. To
2696
+ keep the zero-th shape parameter ``a`` equal 1, use ``f0=1`` or,
2697
+ equivalently, ``fa=1``:
2698
+
2699
+ >>> a1, b1, loc1, scale1 = beta.fit(x, fa=1, floc=0, fscale=1)
2700
+ >>> a1
2701
+ 1
2702
+
2703
+ Not all distributions return estimates for the shape parameters.
2704
+ ``norm`` for example just returns estimates for location and scale:
2705
+
2706
+ >>> from scipy.stats import norm
2707
+ >>> x = norm.rvs(a, b, size=1000, random_state=123)
2708
+ >>> loc1, scale1 = norm.fit(x)
2709
+ >>> loc1, scale1
2710
+ (0.92087172783841631, 2.0015750750324668)
2711
+ """ # noqa: E501
2712
+ method = kwds.get('method', "mle").lower()
2713
+
2714
+ censored = isinstance(data, CensoredData)
2715
+ if censored:
2716
+ if method != 'mle':
2717
+ raise ValueError('For censored data, the method must'
2718
+ ' be "MLE".')
2719
+ if data.num_censored() == 0:
2720
+ # There are no censored values in data, so replace the
2721
+ # CensoredData instance with a regular array.
2722
+ data = data._uncensored
2723
+ censored = False
2724
+
2725
+ Narg = len(args)
2726
+ if Narg > self.numargs:
2727
+ raise TypeError("Too many input arguments.")
2728
+
2729
+ # Check the finiteness of data only if data is not an instance of
2730
+ # CensoredData. The arrays in a CensoredData instance have already
2731
+ # been validated.
2732
+ if not censored:
2733
+ # Note: `ravel()` is called for backwards compatibility.
2734
+ data = np.asarray(data).ravel()
2735
+ if not np.isfinite(data).all():
2736
+ raise ValueError("The data contains non-finite values.")
2737
+
2738
+ start = [None]*2
2739
+ if (Narg < self.numargs) or not ('loc' in kwds and
2740
+ 'scale' in kwds):
2741
+ # get distribution specific starting locations
2742
+ start = self._fitstart(data)
2743
+ args += start[Narg:-2]
2744
+ loc = kwds.pop('loc', start[-2])
2745
+ scale = kwds.pop('scale', start[-1])
2746
+ args += (loc, scale)
2747
+ x0, func, restore, args = self._reduce_func(args, kwds, data=data)
2748
+ optimizer = kwds.pop('optimizer', optimize.fmin)
2749
+ # convert string to function in scipy.optimize
2750
+ optimizer = _fit_determine_optimizer(optimizer)
2751
+ # by now kwds must be empty, since everybody took what they needed
2752
+ if kwds:
2753
+ raise TypeError(f"Unknown arguments: {kwds}.")
2754
+
2755
+ # In some cases, method of moments can be done with fsolve/root
2756
+ # instead of an optimizer, but sometimes no solution exists,
2757
+ # especially when the user fixes parameters. Minimizing the sum
2758
+ # of squares of the error generalizes to these cases.
2759
+ vals = optimizer(func, x0, args=(data,), disp=0)
2760
+ obj = func(vals, data)
2761
+
2762
+ if restore is not None:
2763
+ vals = restore(args, vals)
2764
+ vals = tuple(vals)
2765
+
2766
+ loc, scale, shapes = self._unpack_loc_scale(vals)
2767
+ if not (np.all(self._argcheck(*shapes)) and scale > 0):
2768
+ raise FitError("Optimization converged to parameters that are "
2769
+ "outside the range allowed by the distribution.")
2770
+
2771
+ if method == 'mm':
2772
+ if not np.isfinite(obj):
2773
+ raise FitError("Optimization failed: either a data moment "
2774
+ "or fitted distribution moment is "
2775
+ "non-finite.")
2776
+
2777
+ return vals
2778
+
2779
+ def _fit_loc_scale_support(self, data, *args):
2780
+ """Estimate loc and scale parameters from data accounting for support.
2781
+
2782
+ Parameters
2783
+ ----------
2784
+ data : array_like
2785
+ Data to fit.
2786
+ arg1, arg2, arg3,... : array_like
2787
+ The shape parameter(s) for the distribution (see docstring of the
2788
+ instance object for more information).
2789
+
2790
+ Returns
2791
+ -------
2792
+ Lhat : float
2793
+ Estimated location parameter for the data.
2794
+ Shat : float
2795
+ Estimated scale parameter for the data.
2796
+
2797
+ """
2798
+ if isinstance(data, CensoredData):
2799
+ # For this estimate, "uncensor" the data by taking the
2800
+ # given endpoints as the data for the left- or right-censored
2801
+ # data, and the mean for the interval-censored data.
2802
+ data = data._uncensor()
2803
+ else:
2804
+ data = np.asarray(data)
2805
+
2806
+ # Estimate location and scale according to the method of moments.
2807
+ loc_hat, scale_hat = self.fit_loc_scale(data, *args)
2808
+
2809
+ # Compute the support according to the shape parameters.
2810
+ self._argcheck(*args)
2811
+ _a, _b = self._get_support(*args)
2812
+ a, b = _a, _b
2813
+ support_width = b - a
2814
+
2815
+ # If the support is empty then return the moment-based estimates.
2816
+ if support_width <= 0:
2817
+ return loc_hat, scale_hat
2818
+
2819
+ # Compute the proposed support according to the loc and scale
2820
+ # estimates.
2821
+ a_hat = loc_hat + a * scale_hat
2822
+ b_hat = loc_hat + b * scale_hat
2823
+
2824
+ # Use the moment-based estimates if they are compatible with the data.
2825
+ data_a = np.min(data)
2826
+ data_b = np.max(data)
2827
+ if a_hat < data_a and data_b < b_hat:
2828
+ return loc_hat, scale_hat
2829
+
2830
+ # Otherwise find other estimates that are compatible with the data.
2831
+ data_width = data_b - data_a
2832
+ rel_margin = 0.1
2833
+ margin = data_width * rel_margin
2834
+
2835
+ # For a finite interval, both the location and scale
2836
+ # should have interesting values.
2837
+ if support_width < np.inf:
2838
+ loc_hat = (data_a - a) - margin
2839
+ scale_hat = (data_width + 2 * margin) / support_width
2840
+ return loc_hat, scale_hat
2841
+
2842
+ # For a one-sided interval, use only an interesting location parameter.
2843
+ if a > -np.inf:
2844
+ return (data_a - a) - margin, 1
2845
+ elif b < np.inf:
2846
+ return (data_b - b) + margin, 1
2847
+ else:
2848
+ raise RuntimeError
2849
+
2850
+ def fit_loc_scale(self, data, *args):
2851
+ """
2852
+ Estimate loc and scale parameters from data using 1st and 2nd moments.
2853
+
2854
+ Parameters
2855
+ ----------
2856
+ data : array_like
2857
+ Data to fit.
2858
+ arg1, arg2, arg3,... : array_like
2859
+ The shape parameter(s) for the distribution (see docstring of the
2860
+ instance object for more information).
2861
+
2862
+ Returns
2863
+ -------
2864
+ Lhat : float
2865
+ Estimated location parameter for the data.
2866
+ Shat : float
2867
+ Estimated scale parameter for the data.
2868
+
2869
+ """
2870
+ mu, mu2 = self.stats(*args, **{'moments': 'mv'})
2871
+ tmp = asarray(data)
2872
+ muhat = tmp.mean()
2873
+ mu2hat = tmp.var()
2874
+ Shat = sqrt(mu2hat / mu2)
2875
+ with np.errstate(invalid='ignore'):
2876
+ Lhat = muhat - Shat*mu
2877
+ if not np.isfinite(Lhat):
2878
+ Lhat = 0
2879
+ if not (np.isfinite(Shat) and (0 < Shat)):
2880
+ Shat = 1
2881
+ return Lhat, Shat
2882
+
2883
+ def _entropy(self, *args):
2884
+ def integ(x):
2885
+ val = self._pdf(x, *args)
2886
+ return entr(val)
2887
+
2888
+ # upper limit is often inf, so suppress warnings when integrating
2889
+ _a, _b = self._get_support(*args)
2890
+ with np.errstate(over='ignore'):
2891
+ h = integrate.quad(integ, _a, _b)[0]
2892
+
2893
+ if not np.isnan(h):
2894
+ return h
2895
+ else:
2896
+ # try with different limits if integration problems
2897
+ low, upp = self.ppf([1e-10, 1. - 1e-10], *args)
2898
+ if np.isinf(_b):
2899
+ upper = upp
2900
+ else:
2901
+ upper = _b
2902
+ if np.isinf(_a):
2903
+ lower = low
2904
+ else:
2905
+ lower = _a
2906
+ return integrate.quad(integ, lower, upper)[0]
2907
+
2908
+ def expect(self, func=None, args=(), loc=0, scale=1, lb=None, ub=None,
2909
+ conditional=False, **kwds):
2910
+ """Calculate expected value of a function with respect to the
2911
+ distribution by numerical integration.
2912
+
2913
+ The expected value of a function ``f(x)`` with respect to a
2914
+ distribution ``dist`` is defined as::
2915
+
2916
+ ub
2917
+ E[f(x)] = Integral(f(x) * dist.pdf(x)),
2918
+ lb
2919
+
2920
+ where ``ub`` and ``lb`` are arguments and ``x`` has the ``dist.pdf(x)``
2921
+ distribution. If the bounds ``lb`` and ``ub`` correspond to the
2922
+ support of the distribution, e.g. ``[-inf, inf]`` in the default
2923
+ case, then the integral is the unrestricted expectation of ``f(x)``.
2924
+ Also, the function ``f(x)`` may be defined such that ``f(x)`` is ``0``
2925
+ outside a finite interval in which case the expectation is
2926
+ calculated within the finite range ``[lb, ub]``.
2927
+
2928
+ Parameters
2929
+ ----------
2930
+ func : callable, optional
2931
+ Function for which integral is calculated. Takes only one argument.
2932
+ The default is the identity mapping f(x) = x.
2933
+ args : tuple, optional
2934
+ Shape parameters of the distribution.
2935
+ loc : float, optional
2936
+ Location parameter (default=0).
2937
+ scale : float, optional
2938
+ Scale parameter (default=1).
2939
+ lb, ub : scalar, optional
2940
+ Lower and upper bound for integration. Default is set to the
2941
+ support of the distribution.
2942
+ conditional : bool, optional
2943
+ If True, the integral is corrected by the conditional probability
2944
+ of the integration interval. The return value is the expectation
2945
+ of the function, conditional on being in the given interval.
2946
+ Default is False.
2947
+
2948
+ Additional keyword arguments are passed to the integration routine.
2949
+
2950
+ Returns
2951
+ -------
2952
+ expect : float
2953
+ The calculated expected value.
2954
+
2955
+ Notes
2956
+ -----
2957
+ The integration behavior of this function is inherited from
2958
+ `scipy.integrate.quad`. Neither this function nor
2959
+ `scipy.integrate.quad` can verify whether the integral exists or is
2960
+ finite. For example ``cauchy(0).mean()`` returns ``np.nan`` and
2961
+ ``cauchy(0).expect()`` returns ``0.0``.
2962
+
2963
+ Likewise, the accuracy of results is not verified by the function.
2964
+ `scipy.integrate.quad` is typically reliable for integrals that are
2965
+ numerically favorable, but it is not guaranteed to converge
2966
+ to a correct value for all possible intervals and integrands. This
2967
+ function is provided for convenience; for critical applications,
2968
+ check results against other integration methods.
2969
+
2970
+ The function is not vectorized.
2971
+
2972
+ Examples
2973
+ --------
2974
+
2975
+ To understand the effect of the bounds of integration consider
2976
+
2977
+ >>> from scipy.stats import expon
2978
+ >>> expon(1).expect(lambda x: 1, lb=0.0, ub=2.0)
2979
+ 0.6321205588285578
2980
+
2981
+ This is close to
2982
+
2983
+ >>> expon(1).cdf(2.0) - expon(1).cdf(0.0)
2984
+ 0.6321205588285577
2985
+
2986
+ If ``conditional=True``
2987
+
2988
+ >>> expon(1).expect(lambda x: 1, lb=0.0, ub=2.0, conditional=True)
2989
+ 1.0000000000000002
2990
+
2991
+ The slight deviation from 1 is due to numerical integration.
2992
+
2993
+ The integrand can be treated as a complex-valued function
2994
+ by passing ``complex_func=True`` to `scipy.integrate.quad` .
2995
+
2996
+ >>> import numpy as np
2997
+ >>> from scipy.stats import vonmises
2998
+ >>> res = vonmises(loc=2, kappa=1).expect(lambda x: np.exp(1j*x),
2999
+ ... complex_func=True)
3000
+ >>> res
3001
+ (-0.18576377217422957+0.40590124735052263j)
3002
+
3003
+ >>> np.angle(res) # location of the (circular) distribution
3004
+ 2.0
3005
+
3006
+ """
3007
+ lockwds = {'loc': loc,
3008
+ 'scale': scale}
3009
+ self._argcheck(*args)
3010
+ _a, _b = self._get_support(*args)
3011
+ if func is None:
3012
+ def fun(x, *args):
3013
+ return x * self.pdf(x, *args, **lockwds)
3014
+ else:
3015
+ def fun(x, *args):
3016
+ return func(x) * self.pdf(x, *args, **lockwds)
3017
+ if lb is None:
3018
+ lb = loc + _a * scale
3019
+ if ub is None:
3020
+ ub = loc + _b * scale
3021
+
3022
+ cdf_bounds = self.cdf([lb, ub], *args, **lockwds)
3023
+ invfac = cdf_bounds[1] - cdf_bounds[0]
3024
+
3025
+ kwds['args'] = args
3026
+
3027
+ # split interval to help integrator w/ infinite support; see gh-8928
3028
+ alpha = 0.05 # split body from tails at probability mass `alpha`
3029
+ inner_bounds = np.array([alpha, 1-alpha])
3030
+ cdf_inner_bounds = cdf_bounds[0] + invfac * inner_bounds
3031
+ c, d = loc + self._ppf(cdf_inner_bounds, *args) * scale
3032
+
3033
+ # Do not silence warnings from integration.
3034
+ lbc = integrate.quad(fun, lb, c, **kwds)[0]
3035
+ cd = integrate.quad(fun, c, d, **kwds)[0]
3036
+ dub = integrate.quad(fun, d, ub, **kwds)[0]
3037
+ vals = (lbc + cd + dub)
3038
+
3039
+ if conditional:
3040
+ vals /= invfac
3041
+ return np.array(vals)[()] # make it a numpy scalar like other methods
3042
+
3043
+ def _param_info(self):
3044
+ shape_info = self._shape_info()
3045
+ loc_info = _ShapeInfo("loc", False, (-np.inf, np.inf), (False, False))
3046
+ scale_info = _ShapeInfo("scale", False, (0, np.inf), (False, False))
3047
+ param_info = shape_info + [loc_info, scale_info]
3048
+ return param_info
3049
+
3050
+ # For now, _delta_cdf is a private method.
3051
+ def _delta_cdf(self, x1, x2, *args, loc=0, scale=1):
3052
+ """
3053
+ Compute CDF(x2) - CDF(x1).
3054
+
3055
+ Where x1 is greater than the median, compute SF(x1) - SF(x2),
3056
+ otherwise compute CDF(x2) - CDF(x1).
3057
+
3058
+ This function is only useful if `dist.sf(x, ...)` has an implementation
3059
+ that is numerically more accurate than `1 - dist.cdf(x, ...)`.
3060
+ """
3061
+ cdf1 = self.cdf(x1, *args, loc=loc, scale=scale)
3062
+ # Possible optimizations (needs investigation-these might not be
3063
+ # better):
3064
+ # * Use xpx.apply_where instead of np.where
3065
+ # * Instead of cdf1 > 0.5, compare x1 to the median.
3066
+ result = np.where(cdf1 > 0.5,
3067
+ (self.sf(x1, *args, loc=loc, scale=scale)
3068
+ - self.sf(x2, *args, loc=loc, scale=scale)),
3069
+ self.cdf(x2, *args, loc=loc, scale=scale) - cdf1)
3070
+ if result.ndim == 0:
3071
+ result = result[()]
3072
+ return result
3073
+
3074
+
3075
+ # Helpers for the discrete distributions
3076
+ def _drv2_moment(self, n, *args):
3077
+ """Non-central moment of discrete distribution."""
3078
+ def fun(x):
3079
+ return np.power(x, n) * self._pmf(x, *args)
3080
+
3081
+ _a, _b = self._get_support(*args)
3082
+ return _expect(fun, _a, _b, self._ppf(0.5, *args), self.inc)
3083
+
3084
+
3085
+ def _drv2_ppfsingle(self, q, *args): # Use basic bisection algorithm
3086
+ _a, _b = self._get_support(*args)
3087
+ b = _b
3088
+ a = _a
3089
+
3090
+ step = 10
3091
+ if isinf(b): # Be sure ending point is > q
3092
+ b = float(max(100*q, 10))
3093
+ while 1:
3094
+ if b >= _b:
3095
+ qb = 1.0
3096
+ break
3097
+ qb = self._cdf(b, *args)
3098
+ if (qb < q):
3099
+ b += step
3100
+ step *= 2
3101
+ else:
3102
+ break
3103
+ else:
3104
+ qb = 1.0
3105
+
3106
+ step = 10
3107
+ if isinf(a): # be sure starting point < q
3108
+ a = float(min(-100*q, -10))
3109
+ while 1:
3110
+ if a <= _a:
3111
+ qb = 0.0
3112
+ break
3113
+ qa = self._cdf(a, *args)
3114
+ if (qa > q):
3115
+ a -= step
3116
+ step *= 2
3117
+ else:
3118
+ break
3119
+ else:
3120
+ qa = self._cdf(a, *args)
3121
+
3122
+ if np.isinf(a) or np.isinf(b):
3123
+ message = "Arguments that bracket the requested quantile could not be found."
3124
+ raise RuntimeError(message)
3125
+
3126
+ # maximum number of bisections within the normal float64s
3127
+ # maxiter = int(np.log2(finfo.max) - np.log2(finfo.smallest_normal))
3128
+ maxiter = 2046
3129
+ for i in range(maxiter):
3130
+ if (qa == q):
3131
+ return a
3132
+ if (qb == q):
3133
+ return b
3134
+ if b <= a+1:
3135
+ if qa > q:
3136
+ return a
3137
+ else:
3138
+ return b
3139
+ c = int((a+b)/2.0)
3140
+ qc = self._cdf(c, *args)
3141
+ if (qc < q):
3142
+ if a != c:
3143
+ a = c
3144
+ else:
3145
+ raise RuntimeError('updating stopped, endless loop')
3146
+ qa = qc
3147
+ elif (qc > q):
3148
+ if b != c:
3149
+ b = c
3150
+ else:
3151
+ raise RuntimeError('updating stopped, endless loop')
3152
+ qb = qc
3153
+ else:
3154
+ return c
3155
+
3156
+
3157
+ # Must over-ride one of _pmf or _cdf or pass in
3158
+ # x_k, p(x_k) lists in initialization
3159
+
3160
+
3161
+ class rv_discrete(rv_generic):
3162
+ """A generic discrete random variable class meant for subclassing.
3163
+
3164
+ `rv_discrete` is a base class to construct specific distribution classes
3165
+ and instances for discrete random variables. It can also be used
3166
+ to construct an arbitrary distribution defined by a list of support
3167
+ points and corresponding probabilities.
3168
+
3169
+ Parameters
3170
+ ----------
3171
+ a : float, optional
3172
+ Lower bound of the support of the distribution, default: 0
3173
+ b : float, optional
3174
+ Upper bound of the support of the distribution, default: plus infinity
3175
+ moment_tol : float, optional
3176
+ The tolerance for the generic calculation of moments.
3177
+ values : tuple of two array_like, optional
3178
+ ``(xk, pk)`` where ``xk`` are integers and ``pk`` are the non-zero
3179
+ probabilities between 0 and 1 with ``sum(pk) = 1``. ``xk``
3180
+ and ``pk`` must have the same shape, and ``xk`` must be unique.
3181
+ inc : integer, optional
3182
+ Increment for the support of the distribution.
3183
+ Default is 1. (other values have not been tested)
3184
+ badvalue : float, optional
3185
+ The value in a result arrays that indicates a value that for which
3186
+ some argument restriction is violated, default is np.nan.
3187
+ name : str, optional
3188
+ The name of the instance. This string is used to construct the default
3189
+ example for distributions.
3190
+ longname : str, optional
3191
+ This string is used as part of the first line of the docstring returned
3192
+ when a subclass has no docstring of its own. Note: `longname` exists
3193
+ for backwards compatibility, do not use for new subclasses.
3194
+ shapes : str, optional
3195
+ The shape of the distribution. For example "m, n" for a distribution
3196
+ that takes two integers as the two shape arguments for all its methods
3197
+ If not provided, shape parameters will be inferred from
3198
+ the signatures of the private methods, ``_pmf`` and ``_cdf`` of
3199
+ the instance.
3200
+ seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
3201
+ If `seed` is None (or `np.random`), the `numpy.random.RandomState`
3202
+ singleton is used.
3203
+ If `seed` is an int, a new ``RandomState`` instance is used,
3204
+ seeded with `seed`.
3205
+ If `seed` is already a ``Generator`` or ``RandomState`` instance then
3206
+ that instance is used.
3207
+
3208
+ Attributes
3209
+ ----------
3210
+ a, b : float, optional
3211
+ Lower/upper bound of the support of the unshifted/unscaled distribution.
3212
+ This value is unaffected by the `loc` and `scale` parameters.
3213
+ To calculate the support of the shifted/scaled distribution,
3214
+ use the `support` method.
3215
+
3216
+ Methods
3217
+ -------
3218
+ rvs
3219
+ pmf
3220
+ logpmf
3221
+ cdf
3222
+ logcdf
3223
+ sf
3224
+ logsf
3225
+ ppf
3226
+ isf
3227
+ moment
3228
+ stats
3229
+ entropy
3230
+ expect
3231
+ median
3232
+ mean
3233
+ std
3234
+ var
3235
+ interval
3236
+ __call__
3237
+ support
3238
+
3239
+ Notes
3240
+ -----
3241
+ This class is similar to `rv_continuous`. Whether a shape parameter is
3242
+ valid is decided by an ``_argcheck`` method (which defaults to checking
3243
+ that its arguments are strictly positive.)
3244
+ The main differences are as follows.
3245
+
3246
+ - The support of the distribution is a set of integers.
3247
+ - Instead of the probability density function, ``pdf`` (and the
3248
+ corresponding private ``_pdf``), this class defines the
3249
+ *probability mass function*, `pmf` (and the corresponding
3250
+ private ``_pmf``.)
3251
+ - There is no ``scale`` parameter.
3252
+ - The default implementations of methods (e.g. ``_cdf``) are not designed
3253
+ for distributions with support that is unbounded below (i.e.
3254
+ ``a=-np.inf``), so they must be overridden.
3255
+
3256
+ To create a new discrete distribution, we would do the following:
3257
+
3258
+ >>> from scipy.stats import rv_discrete
3259
+ >>> class poisson_gen(rv_discrete):
3260
+ ... "Poisson distribution"
3261
+ ... def _pmf(self, k, mu):
3262
+ ... return exp(-mu) * mu**k / factorial(k)
3263
+
3264
+ and create an instance::
3265
+
3266
+ >>> poisson = poisson_gen(name="poisson")
3267
+
3268
+ Note that above we defined the Poisson distribution in the standard form.
3269
+ Shifting the distribution can be done by providing the ``loc`` parameter
3270
+ to the methods of the instance. For example, ``poisson.pmf(x, mu, loc)``
3271
+ delegates the work to ``poisson._pmf(x-loc, mu)``.
3272
+
3273
+ **Discrete distributions from a list of probabilities**
3274
+
3275
+ Alternatively, you can construct an arbitrary discrete rv defined
3276
+ on a finite set of values ``xk`` with ``Prob{X=xk} = pk`` by using the
3277
+ ``values`` keyword argument to the `rv_discrete` constructor.
3278
+
3279
+ **Deepcopying / Pickling**
3280
+
3281
+ If a distribution or frozen distribution is deepcopied (pickled/unpickled,
3282
+ etc.), any underlying random number generator is deepcopied with it. An
3283
+ implication is that if a distribution relies on the singleton RandomState
3284
+ before copying, it will rely on a copy of that random state after copying,
3285
+ and ``np.random.seed`` will no longer control the state.
3286
+
3287
+ Examples
3288
+ --------
3289
+ Custom made discrete distribution:
3290
+
3291
+ >>> import numpy as np
3292
+ >>> from scipy import stats
3293
+ >>> xk = np.arange(7)
3294
+ >>> pk = (0.1, 0.2, 0.3, 0.1, 0.1, 0.0, 0.2)
3295
+ >>> custm = stats.rv_discrete(name='custm', values=(xk, pk))
3296
+ >>>
3297
+ >>> import matplotlib.pyplot as plt
3298
+ >>> fig, ax = plt.subplots(1, 1)
3299
+ >>> ax.plot(xk, custm.pmf(xk), 'ro', ms=12, mec='r')
3300
+ >>> ax.vlines(xk, 0, custm.pmf(xk), colors='r', lw=4)
3301
+ >>> plt.show()
3302
+
3303
+ Random number generation:
3304
+
3305
+ >>> R = custm.rvs(size=100)
3306
+
3307
+ """
3308
+ def __new__(cls, a=0, b=inf, name=None, badvalue=None,
3309
+ moment_tol=1e-8, values=None, inc=1, longname=None,
3310
+ shapes=None, seed=None):
3311
+
3312
+ if values is not None:
3313
+ # dispatch to a subclass
3314
+ return super().__new__(rv_sample)
3315
+ else:
3316
+ # business as usual
3317
+ return super().__new__(cls)
3318
+
3319
+ def __init__(self, a=0, b=inf, name=None, badvalue=None,
3320
+ moment_tol=1e-8, values=None, inc=1, longname=None,
3321
+ shapes=None, seed=None):
3322
+
3323
+ super().__init__(seed)
3324
+
3325
+ # cf generic freeze
3326
+ self._ctor_param = dict(
3327
+ a=a, b=b, name=name, badvalue=badvalue,
3328
+ moment_tol=moment_tol, values=values, inc=inc,
3329
+ longname=longname, shapes=shapes, seed=seed)
3330
+
3331
+ if badvalue is None:
3332
+ badvalue = nan
3333
+ self.badvalue = badvalue
3334
+ self.a = a
3335
+ self.b = b
3336
+ self.moment_tol = moment_tol
3337
+ self.inc = inc
3338
+ self.shapes = shapes
3339
+
3340
+ if values is not None:
3341
+ raise ValueError("rv_discrete.__init__(..., values != None, ...)")
3342
+
3343
+ self._construct_argparser(meths_to_inspect=[self._pmf, self._cdf],
3344
+ locscale_in='loc=0',
3345
+ # scale=1 for discrete RVs
3346
+ locscale_out='loc, 1')
3347
+ self._attach_methods()
3348
+ self._construct_docstrings(name, longname)
3349
+
3350
+ def __getstate__(self):
3351
+ dct = self.__dict__.copy()
3352
+ # these methods will be remade in __setstate__
3353
+ attrs = ["_parse_args", "_parse_args_stats", "_parse_args_rvs",
3354
+ "_cdfvec", "_ppfvec", "generic_moment"]
3355
+ [dct.pop(attr, None) for attr in attrs]
3356
+ return dct
3357
+
3358
+ def _attach_methods(self):
3359
+ """Attaches dynamically created methods to the rv_discrete instance."""
3360
+ self._cdfvec = vectorize(self._cdf_single, otypes='d')
3361
+ self.vecentropy = vectorize(self._entropy)
3362
+
3363
+ # _attach_methods is responsible for calling _attach_argparser_methods
3364
+ self._attach_argparser_methods()
3365
+
3366
+ # nin correction needs to be after we know numargs
3367
+ # correct nin for generic moment vectorization
3368
+ _vec_generic_moment = vectorize(_drv2_moment, otypes='d')
3369
+ _vec_generic_moment.nin = self.numargs + 2
3370
+ self.generic_moment = types.MethodType(_vec_generic_moment, self)
3371
+
3372
+ # correct nin for ppf vectorization
3373
+ _vppf = vectorize(_drv2_ppfsingle, otypes='d')
3374
+ _vppf.nin = self.numargs + 2
3375
+ self._ppfvec = types.MethodType(_vppf, self)
3376
+
3377
+ # now that self.numargs is defined, we can adjust nin
3378
+ self._cdfvec.nin = self.numargs + 1
3379
+
3380
+ def _construct_docstrings(self, name, longname):
3381
+ if name is None:
3382
+ name = 'Distribution'
3383
+ self.name = name
3384
+
3385
+ # generate docstring for subclass instances
3386
+ if longname is None:
3387
+ if name[0] in ['aeiouAEIOU']:
3388
+ hstr = "An "
3389
+ else:
3390
+ hstr = "A "
3391
+ longname = hstr + name
3392
+
3393
+ if sys.flags.optimize < 2:
3394
+ # Skip adding docstrings if interpreter is run with -OO
3395
+ if self.__doc__ is None:
3396
+ self._construct_default_doc(longname=longname,
3397
+ docdict=docdict_discrete,
3398
+ discrete='discrete')
3399
+ else:
3400
+ dct = dict(distdiscrete)
3401
+ self._construct_doc(docdict_discrete, dct.get(self.name))
3402
+
3403
+ # discrete RV do not have the scale parameter, remove it
3404
+ self.__doc__ = self.__doc__.replace(
3405
+ '\n scale : array_like, '
3406
+ 'optional\n scale parameter (default=1)', '')
3407
+
3408
+ def _updated_ctor_param(self):
3409
+ """Return the current version of _ctor_param, possibly updated by user.
3410
+
3411
+ Used by freezing.
3412
+ Keep this in sync with the signature of __init__.
3413
+ """
3414
+ dct = self._ctor_param.copy()
3415
+ dct['a'] = self.a
3416
+ dct['b'] = self.b
3417
+ dct['badvalue'] = self.badvalue
3418
+ dct['moment_tol'] = self.moment_tol
3419
+ dct['inc'] = self.inc
3420
+ dct['name'] = self.name
3421
+ dct['shapes'] = self.shapes
3422
+ return dct
3423
+
3424
+ def _nonzero(self, k, *args):
3425
+ return floor(k) == k
3426
+
3427
+ def _pmf(self, k, *args):
3428
+ return self._cdf(k, *args) - self._cdf(k-1, *args)
3429
+
3430
+ def _logpmf(self, k, *args):
3431
+ with np.errstate(divide='ignore'):
3432
+ return log(self._pmf(k, *args))
3433
+
3434
+ def _logpxf(self, k, *args):
3435
+ # continuous distributions have PDF, discrete have PMF, but sometimes
3436
+ # the distinction doesn't matter. This lets us use `_logpxf` for both
3437
+ # discrete and continuous distributions.
3438
+ return self._logpmf(k, *args)
3439
+
3440
+ def _unpack_loc_scale(self, theta):
3441
+ try:
3442
+ loc = theta[-1]
3443
+ scale = 1
3444
+ args = tuple(theta[:-1])
3445
+ except IndexError as e:
3446
+ raise ValueError("Not enough input arguments.") from e
3447
+ return loc, scale, args
3448
+
3449
+ def _cdf_single(self, k, *args):
3450
+ _a, _b = self._get_support(*args)
3451
+ m = arange(int(_a), k+1)
3452
+ return np.sum(self._pmf(m, *args), axis=0)
3453
+
3454
+ def _cdf(self, x, *args):
3455
+ k = floor(x).astype(np.float64)
3456
+ return self._cdfvec(k, *args)
3457
+
3458
+ # generic _logcdf, _sf, _logsf, _ppf, _isf, _rvs defined in rv_generic
3459
+
3460
+ def rvs(self, *args, **kwargs):
3461
+ """Random variates of given type.
3462
+
3463
+ Parameters
3464
+ ----------
3465
+ arg1, arg2, arg3,... : array_like
3466
+ The shape parameter(s) for the distribution (see docstring of the
3467
+ instance object for more information).
3468
+ loc : array_like, optional
3469
+ Location parameter (default=0).
3470
+ size : int or tuple of ints, optional
3471
+ Defining number of random variates (Default is 1). Note that `size`
3472
+ has to be given as keyword, not as positional argument.
3473
+ random_state : {None, int, `numpy.random.Generator`,
3474
+ `numpy.random.RandomState`}, optional
3475
+
3476
+ If `random_state` is None (or `np.random`), the
3477
+ `numpy.random.RandomState` singleton is used.
3478
+ If `random_state` is an int, a new ``RandomState`` instance is
3479
+ used, seeded with `random_state`.
3480
+ If `random_state` is already a ``Generator`` or ``RandomState``
3481
+ instance, that instance is used.
3482
+
3483
+ Returns
3484
+ -------
3485
+ rvs : ndarray or scalar
3486
+ Random variates of given `size`.
3487
+
3488
+ """
3489
+ kwargs['discrete'] = True
3490
+ return super().rvs(*args, **kwargs)
3491
+
3492
+ def pmf(self, k, *args, **kwds):
3493
+ """Probability mass function at k of the given RV.
3494
+
3495
+ Parameters
3496
+ ----------
3497
+ k : array_like
3498
+ Quantiles.
3499
+ arg1, arg2, arg3,... : array_like
3500
+ The shape parameter(s) for the distribution (see docstring of the
3501
+ instance object for more information)
3502
+ loc : array_like, optional
3503
+ Location parameter (default=0).
3504
+
3505
+ Returns
3506
+ -------
3507
+ pmf : array_like
3508
+ Probability mass function evaluated at k
3509
+
3510
+ """
3511
+ args, loc, _ = self._parse_args(*args, **kwds)
3512
+ k, loc = map(asarray, (k, loc))
3513
+ args = tuple(map(asarray, args))
3514
+ _a, _b = self._get_support(*args)
3515
+ k = asarray(k-loc)
3516
+ cond0 = self._argcheck(*args)
3517
+ cond1 = (k >= _a) & (k <= _b)
3518
+ if not isinstance(self, rv_sample):
3519
+ cond1 = cond1 & self._nonzero(k, *args)
3520
+ cond = cond0 & cond1
3521
+ output = zeros(shape(cond), 'd')
3522
+ place(output, (1-cond0) + np.isnan(k), self.badvalue)
3523
+ if np.any(cond):
3524
+ goodargs = argsreduce(cond, *((k,)+args))
3525
+ place(output, cond, np.clip(self._pmf(*goodargs), 0, 1))
3526
+ if output.ndim == 0:
3527
+ return output[()]
3528
+ return output
3529
+
3530
+ def logpmf(self, k, *args, **kwds):
3531
+ """Log of the probability mass function at k of the given RV.
3532
+
3533
+ Parameters
3534
+ ----------
3535
+ k : array_like
3536
+ Quantiles.
3537
+ arg1, arg2, arg3,... : array_like
3538
+ The shape parameter(s) for the distribution (see docstring of the
3539
+ instance object for more information).
3540
+ loc : array_like, optional
3541
+ Location parameter. Default is 0.
3542
+
3543
+ Returns
3544
+ -------
3545
+ logpmf : array_like
3546
+ Log of the probability mass function evaluated at k.
3547
+
3548
+ """
3549
+ args, loc, _ = self._parse_args(*args, **kwds)
3550
+ k, loc = map(asarray, (k, loc))
3551
+ args = tuple(map(asarray, args))
3552
+ _a, _b = self._get_support(*args)
3553
+ k = asarray(k-loc)
3554
+ cond0 = self._argcheck(*args)
3555
+ cond1 = (k >= _a) & (k <= _b)
3556
+ if not isinstance(self, rv_sample):
3557
+ cond1 = cond1 & self._nonzero(k, *args)
3558
+ cond = cond0 & cond1
3559
+ output = empty(shape(cond), 'd')
3560
+ output.fill(-inf)
3561
+ place(output, (1-cond0) + np.isnan(k), self.badvalue)
3562
+ if np.any(cond):
3563
+ goodargs = argsreduce(cond, *((k,)+args))
3564
+ place(output, cond, self._logpmf(*goodargs))
3565
+ if output.ndim == 0:
3566
+ return output[()]
3567
+ return output
3568
+
3569
+ def cdf(self, k, *args, **kwds):
3570
+ """Cumulative distribution function of the given RV.
3571
+
3572
+ Parameters
3573
+ ----------
3574
+ k : array_like, int
3575
+ Quantiles.
3576
+ arg1, arg2, arg3,... : array_like
3577
+ The shape parameter(s) for the distribution (see docstring of the
3578
+ instance object for more information).
3579
+ loc : array_like, optional
3580
+ Location parameter (default=0).
3581
+
3582
+ Returns
3583
+ -------
3584
+ cdf : ndarray
3585
+ Cumulative distribution function evaluated at `k`.
3586
+
3587
+ """
3588
+ args, loc, _ = self._parse_args(*args, **kwds)
3589
+ k, loc = map(asarray, (k, loc))
3590
+ args = tuple(map(asarray, args))
3591
+ _a, _b = self._get_support(*args)
3592
+ k = asarray(k-loc)
3593
+ cond0 = self._argcheck(*args)
3594
+ cond1 = (k >= _a) & (k < _b)
3595
+ cond2 = (k >= _b)
3596
+ cond3 = np.isneginf(k)
3597
+ cond = cond0 & cond1 & np.isfinite(k)
3598
+
3599
+ output = zeros(shape(cond), 'd')
3600
+ place(output, cond2*(cond0 == cond0), 1.0)
3601
+ place(output, cond3*(cond0 == cond0), 0.0)
3602
+ place(output, (1-cond0) + np.isnan(k), self.badvalue)
3603
+
3604
+ if np.any(cond):
3605
+ goodargs = argsreduce(cond, *((k,)+args))
3606
+ place(output, cond, np.clip(self._cdf(*goodargs), 0, 1))
3607
+ if output.ndim == 0:
3608
+ return output[()]
3609
+ return output
3610
+
3611
+ def logcdf(self, k, *args, **kwds):
3612
+ """Log of the cumulative distribution function at k of the given RV.
3613
+
3614
+ Parameters
3615
+ ----------
3616
+ k : array_like, int
3617
+ Quantiles.
3618
+ arg1, arg2, arg3,... : array_like
3619
+ The shape parameter(s) for the distribution (see docstring of the
3620
+ instance object for more information).
3621
+ loc : array_like, optional
3622
+ Location parameter (default=0).
3623
+
3624
+ Returns
3625
+ -------
3626
+ logcdf : array_like
3627
+ Log of the cumulative distribution function evaluated at k.
3628
+
3629
+ """
3630
+ args, loc, _ = self._parse_args(*args, **kwds)
3631
+ k, loc = map(asarray, (k, loc))
3632
+ args = tuple(map(asarray, args))
3633
+ _a, _b = self._get_support(*args)
3634
+ k = asarray(k-loc)
3635
+ cond0 = self._argcheck(*args)
3636
+ cond1 = (k >= _a) & (k < _b)
3637
+ cond2 = (k >= _b)
3638
+ cond = cond0 & cond1
3639
+ output = empty(shape(cond), 'd')
3640
+ output.fill(-inf)
3641
+ place(output, (1-cond0) + np.isnan(k), self.badvalue)
3642
+ place(output, cond2*(cond0 == cond0), 0.0)
3643
+
3644
+ if np.any(cond):
3645
+ goodargs = argsreduce(cond, *((k,)+args))
3646
+ place(output, cond, self._logcdf(*goodargs))
3647
+ if output.ndim == 0:
3648
+ return output[()]
3649
+ return output
3650
+
3651
+ def sf(self, k, *args, **kwds):
3652
+ """Survival function (1 - `cdf`) at k of the given RV.
3653
+
3654
+ Parameters
3655
+ ----------
3656
+ k : array_like
3657
+ Quantiles.
3658
+ arg1, arg2, arg3,... : array_like
3659
+ The shape parameter(s) for the distribution (see docstring of the
3660
+ instance object for more information).
3661
+ loc : array_like, optional
3662
+ Location parameter (default=0).
3663
+
3664
+ Returns
3665
+ -------
3666
+ sf : array_like
3667
+ Survival function evaluated at k.
3668
+
3669
+ """
3670
+ args, loc, _ = self._parse_args(*args, **kwds)
3671
+ k, loc = map(asarray, (k, loc))
3672
+ args = tuple(map(asarray, args))
3673
+ _a, _b = self._get_support(*args)
3674
+ k = asarray(k-loc)
3675
+ cond0 = self._argcheck(*args)
3676
+ cond1 = (k >= _a) & (k < _b)
3677
+ cond2 = ((k < _a) | np.isneginf(k)) & cond0
3678
+ cond = cond0 & cond1 & np.isfinite(k)
3679
+ output = zeros(shape(cond), 'd')
3680
+ place(output, (1-cond0) + np.isnan(k), self.badvalue)
3681
+ place(output, cond2, 1.0)
3682
+ if np.any(cond):
3683
+ goodargs = argsreduce(cond, *((k,)+args))
3684
+ place(output, cond, np.clip(self._sf(*goodargs), 0, 1))
3685
+ if output.ndim == 0:
3686
+ return output[()]
3687
+ return output
3688
+
3689
+ def logsf(self, k, *args, **kwds):
3690
+ """Log of the survival function of the given RV.
3691
+
3692
+ Returns the log of the "survival function," defined as 1 - `cdf`,
3693
+ evaluated at `k`.
3694
+
3695
+ Parameters
3696
+ ----------
3697
+ k : array_like
3698
+ Quantiles.
3699
+ arg1, arg2, arg3,... : array_like
3700
+ The shape parameter(s) for the distribution (see docstring of the
3701
+ instance object for more information).
3702
+ loc : array_like, optional
3703
+ Location parameter (default=0).
3704
+
3705
+ Returns
3706
+ -------
3707
+ logsf : ndarray
3708
+ Log of the survival function evaluated at `k`.
3709
+
3710
+ """
3711
+ args, loc, _ = self._parse_args(*args, **kwds)
3712
+ k, loc = map(asarray, (k, loc))
3713
+ args = tuple(map(asarray, args))
3714
+ _a, _b = self._get_support(*args)
3715
+ k = asarray(k-loc)
3716
+ cond0 = self._argcheck(*args)
3717
+ cond1 = (k >= _a) & (k < _b)
3718
+ cond2 = (k < _a) & cond0
3719
+ cond = cond0 & cond1
3720
+ output = empty(shape(cond), 'd')
3721
+ output.fill(-inf)
3722
+ place(output, (1-cond0) + np.isnan(k), self.badvalue)
3723
+ place(output, cond2, 0.0)
3724
+ if np.any(cond):
3725
+ goodargs = argsreduce(cond, *((k,)+args))
3726
+ place(output, cond, self._logsf(*goodargs))
3727
+ if output.ndim == 0:
3728
+ return output[()]
3729
+ return output
3730
+
3731
+ def ppf(self, q, *args, **kwds):
3732
+ """Percent point function (inverse of `cdf`) at q of the given RV.
3733
+
3734
+ Parameters
3735
+ ----------
3736
+ q : array_like
3737
+ Lower tail probability.
3738
+ arg1, arg2, arg3,... : array_like
3739
+ The shape parameter(s) for the distribution (see docstring of the
3740
+ instance object for more information).
3741
+ loc : array_like, optional
3742
+ Location parameter (default=0).
3743
+
3744
+ Returns
3745
+ -------
3746
+ k : array_like
3747
+ Quantile corresponding to the lower tail probability, q.
3748
+
3749
+ """
3750
+ args, loc, _ = self._parse_args(*args, **kwds)
3751
+ q, loc = map(asarray, (q, loc))
3752
+ args = tuple(map(asarray, args))
3753
+ _a, _b = self._get_support(*args)
3754
+ cond0 = self._argcheck(*args) & (loc == loc)
3755
+ cond1 = (q > 0) & (q < 1)
3756
+ cond2 = (q == 1) & cond0
3757
+ cond = cond0 & cond1
3758
+ output = np.full(shape(cond), fill_value=self.badvalue, dtype='d')
3759
+ # output type 'd' to handle nin and inf
3760
+ place(output, (q == 0)*(cond == cond), _a-1 + loc)
3761
+ place(output, cond2, _b + loc)
3762
+ if np.any(cond):
3763
+ goodargs = argsreduce(cond, *((q,)+args+(loc,)))
3764
+ loc, goodargs = goodargs[-1], goodargs[:-1]
3765
+ place(output, cond, self._ppf(*goodargs) + loc)
3766
+
3767
+ if output.ndim == 0:
3768
+ return output[()]
3769
+ return output
3770
+
3771
+ def isf(self, q, *args, **kwds):
3772
+ """Inverse survival function (inverse of `sf`) at q of the given RV.
3773
+
3774
+ Parameters
3775
+ ----------
3776
+ q : array_like
3777
+ Upper tail probability.
3778
+ arg1, arg2, arg3,... : array_like
3779
+ The shape parameter(s) for the distribution (see docstring of the
3780
+ instance object for more information).
3781
+ loc : array_like, optional
3782
+ Location parameter (default=0).
3783
+
3784
+ Returns
3785
+ -------
3786
+ k : ndarray or scalar
3787
+ Quantile corresponding to the upper tail probability, q.
3788
+
3789
+ """
3790
+ args, loc, _ = self._parse_args(*args, **kwds)
3791
+ q, loc = map(asarray, (q, loc))
3792
+ args = tuple(map(asarray, args))
3793
+ _a, _b = self._get_support(*args)
3794
+ cond0 = self._argcheck(*args) & (loc == loc)
3795
+ cond1 = (q > 0) & (q < 1)
3796
+ cond2 = (q == 1) & cond0
3797
+ cond3 = (q == 0) & cond0
3798
+ cond = cond0 & cond1
3799
+
3800
+ # same problem as with ppf; copied from ppf and changed
3801
+ output = np.full(shape(cond), fill_value=self.badvalue, dtype='d')
3802
+ # output type 'd' to handle nin and inf
3803
+ lower_bound = _a - 1 + loc
3804
+ upper_bound = _b + loc
3805
+ place(output, cond2*(cond == cond), lower_bound)
3806
+ place(output, cond3*(cond == cond), upper_bound)
3807
+
3808
+ # call place only if at least 1 valid argument
3809
+ if np.any(cond):
3810
+ goodargs = argsreduce(cond, *((q,)+args+(loc,)))
3811
+ loc, goodargs = goodargs[-1], goodargs[:-1]
3812
+ # PB same as ticket 766
3813
+ place(output, cond, self._isf(*goodargs) + loc)
3814
+
3815
+ if output.ndim == 0:
3816
+ return output[()]
3817
+ return output
3818
+
3819
+ def _entropy(self, *args):
3820
+ if hasattr(self, 'pk'):
3821
+ return stats.entropy(self.pk)
3822
+ else:
3823
+ _a, _b = self._get_support(*args)
3824
+ return _expect(lambda x: entr(self._pmf(x, *args)),
3825
+ _a, _b, self._ppf(0.5, *args), self.inc)
3826
+
3827
+ def expect(self, func=None, args=(), loc=0, lb=None, ub=None,
3828
+ conditional=False, maxcount=1000, tolerance=1e-10, chunksize=32):
3829
+ """
3830
+ Calculate expected value of a function with respect to the distribution
3831
+ for discrete distribution by numerical summation.
3832
+
3833
+ Parameters
3834
+ ----------
3835
+ func : callable, optional
3836
+ Function for which the expectation value is calculated.
3837
+ Takes only one argument.
3838
+ The default is the identity mapping f(k) = k.
3839
+ args : tuple, optional
3840
+ Shape parameters of the distribution.
3841
+ loc : float, optional
3842
+ Location parameter.
3843
+ Default is 0.
3844
+ lb, ub : int, optional
3845
+ Lower and upper bound for the summation, default is set to the
3846
+ support of the distribution, inclusive (``lb <= k <= ub``).
3847
+ conditional : bool, optional
3848
+ If true then the expectation is corrected by the conditional
3849
+ probability of the summation interval. The return value is the
3850
+ expectation of the function, `func`, conditional on being in
3851
+ the given interval (k such that ``lb <= k <= ub``).
3852
+ Default is False.
3853
+ maxcount : int, optional
3854
+ Maximal number of terms to evaluate (to avoid an endless loop for
3855
+ an infinite sum). Default is 1000.
3856
+ tolerance : float, optional
3857
+ Absolute tolerance for the summation. Default is 1e-10.
3858
+ chunksize : int, optional
3859
+ Iterate over the support of a distributions in chunks of this size.
3860
+ Default is 32.
3861
+
3862
+ Returns
3863
+ -------
3864
+ expect : float
3865
+ Expected value.
3866
+
3867
+ Notes
3868
+ -----
3869
+ For heavy-tailed distributions, the expected value may or
3870
+ may not exist,
3871
+ depending on the function, `func`. If it does exist, but the
3872
+ sum converges
3873
+ slowly, the accuracy of the result may be rather low. For instance, for
3874
+ ``zipf(4)``, accuracy for mean, variance in example is only 1e-5.
3875
+ increasing `maxcount` and/or `chunksize` may improve the result,
3876
+ but may also make zipf very slow.
3877
+
3878
+ The function is not vectorized.
3879
+
3880
+ """
3881
+ # Although `args` is just the shape parameters, `poisson_binom` needs this
3882
+ # to split the vector-valued shape into a tuple of separate shapes
3883
+ args, _, _ = self._parse_args(*args)
3884
+
3885
+ if func is None:
3886
+ def fun(x):
3887
+ # loc and args from outer scope
3888
+ return (x+loc)*self._pmf(x, *args)
3889
+ else:
3890
+ def fun(x):
3891
+ # loc and args from outer scope
3892
+ return func(x+loc)*self._pmf(x, *args)
3893
+ # used pmf because _pmf does not check support in randint and there
3894
+ # might be problems(?) with correct self.a, self.b at this stage maybe
3895
+ # not anymore, seems to work now with _pmf
3896
+
3897
+ _a, _b = self._get_support(*args)
3898
+ if lb is None:
3899
+ lb = _a
3900
+ else:
3901
+ lb = lb - loc # convert bound for standardized distribution
3902
+ if ub is None:
3903
+ ub = _b
3904
+ else:
3905
+ ub = ub - loc # convert bound for standardized distribution
3906
+ if conditional:
3907
+ invfac = self.sf(lb-1, *args) - self.sf(ub, *args)
3908
+ else:
3909
+ invfac = 1.0
3910
+
3911
+ if isinstance(self, rv_sample):
3912
+ res = self._expect(fun, lb, ub)
3913
+ return res / invfac
3914
+
3915
+ # iterate over the support, starting from the median
3916
+ x0 = self._ppf(0.5, *args)
3917
+ res = _expect(fun, lb, ub, x0, self.inc, maxcount, tolerance, chunksize)
3918
+ return res / invfac
3919
+
3920
+ def _param_info(self):
3921
+ shape_info = self._shape_info()
3922
+ loc_info = _ShapeInfo("loc", True, (-np.inf, np.inf), (False, False))
3923
+ param_info = shape_info + [loc_info]
3924
+ return param_info
3925
+
3926
+
3927
+ def _expect(fun, lb, ub, x0, inc, maxcount=1000, tolerance=1e-10,
3928
+ chunksize=32):
3929
+ """Helper for computing the expectation value of `fun`."""
3930
+ # short-circuit if the support size is small enough
3931
+ if (ub - lb) <= chunksize:
3932
+ supp = np.arange(lb, ub+1, inc)
3933
+ vals = fun(supp)
3934
+ return np.sum(vals)
3935
+
3936
+ # otherwise, iterate starting from x0
3937
+ if x0 < lb:
3938
+ x0 = lb
3939
+ if x0 > ub:
3940
+ x0 = ub
3941
+
3942
+ count, tot = 0, 0.
3943
+ # iterate over [x0, ub] inclusive
3944
+ for x in _iter_chunked(x0, ub+1, chunksize=chunksize, inc=inc):
3945
+ count += x.size
3946
+ delta = np.sum(fun(x))
3947
+ tot += delta
3948
+ if abs(delta) < tolerance * x.size:
3949
+ break
3950
+ if count > maxcount:
3951
+ warnings.warn('expect(): sum did not converge',
3952
+ RuntimeWarning, stacklevel=3)
3953
+ return tot
3954
+
3955
+ # iterate over [lb, x0)
3956
+ for x in _iter_chunked(x0-1, lb-1, chunksize=chunksize, inc=-inc):
3957
+ count += x.size
3958
+ delta = np.sum(fun(x))
3959
+ tot += delta
3960
+ if abs(delta) < tolerance * x.size:
3961
+ break
3962
+ if count > maxcount:
3963
+ warnings.warn('expect(): sum did not converge',
3964
+ RuntimeWarning, stacklevel=3)
3965
+ break
3966
+
3967
+ return tot
3968
+
3969
+
3970
+ def _iter_chunked(x0, x1, chunksize=4, inc=1):
3971
+ """Iterate from x0 to x1 in chunks of chunksize and steps inc.
3972
+
3973
+ x0 must be finite, x1 need not be. In the latter case, the iterator is
3974
+ infinite.
3975
+ Handles both x0 < x1 and x0 > x1. In the latter case, iterates downwards
3976
+ (make sure to set inc < 0.)
3977
+
3978
+ >>> from scipy.stats._distn_infrastructure import _iter_chunked
3979
+ >>> [x for x in _iter_chunked(2, 5, inc=2)]
3980
+ [array([2, 4])]
3981
+ >>> [x for x in _iter_chunked(2, 11, inc=2)]
3982
+ [array([2, 4, 6, 8]), array([10])]
3983
+ >>> [x for x in _iter_chunked(2, -5, inc=-2)]
3984
+ [array([ 2, 0, -2, -4])]
3985
+ >>> [x for x in _iter_chunked(2, -9, inc=-2)]
3986
+ [array([ 2, 0, -2, -4]), array([-6, -8])]
3987
+
3988
+ """
3989
+ if inc == 0:
3990
+ raise ValueError('Cannot increment by zero.')
3991
+ if chunksize <= 0:
3992
+ raise ValueError(f'Chunk size must be positive; got {chunksize}.')
3993
+
3994
+ s = 1 if inc > 0 else -1
3995
+ stepsize = abs(chunksize * inc)
3996
+
3997
+ x = np.copy(x0)
3998
+ while (x - x1) * inc < 0:
3999
+ delta = min(stepsize, abs(x - x1))
4000
+ step = delta * s
4001
+ supp = np.arange(x, x + step, inc)
4002
+ x += step
4003
+ yield supp
4004
+
4005
+
4006
+ class rv_sample(rv_discrete):
4007
+ """A 'sample' discrete distribution defined by the support and values.
4008
+
4009
+ The ctor ignores most of the arguments, only needs the `values` argument.
4010
+ """
4011
+
4012
+ def __init__(self, a=0, b=inf, name=None, badvalue=None,
4013
+ moment_tol=1e-8, values=None, inc=1, longname=None,
4014
+ shapes=None, seed=None):
4015
+
4016
+ super(rv_discrete, self).__init__(seed)
4017
+
4018
+ if values is None:
4019
+ raise ValueError("rv_sample.__init__(..., values=None,...)")
4020
+
4021
+ # cf generic freeze
4022
+ self._ctor_param = dict(
4023
+ a=a, b=b, name=name, badvalue=badvalue,
4024
+ moment_tol=moment_tol, values=values, inc=inc,
4025
+ longname=longname, shapes=shapes, seed=seed)
4026
+
4027
+ if badvalue is None:
4028
+ badvalue = nan
4029
+ self.badvalue = badvalue
4030
+ self.moment_tol = moment_tol
4031
+ self.inc = inc
4032
+ self.shapes = shapes
4033
+ self.vecentropy = self._entropy
4034
+
4035
+ xk, pk = values
4036
+
4037
+ if np.shape(xk) != np.shape(pk):
4038
+ raise ValueError("xk and pk must have the same shape.")
4039
+ if np.less(pk, 0.0).any():
4040
+ raise ValueError("All elements of pk must be non-negative.")
4041
+ if not np.allclose(np.sum(pk), 1):
4042
+ raise ValueError("The sum of provided pk is not 1.")
4043
+ if not len(set(np.ravel(xk))) == np.size(xk):
4044
+ raise ValueError("xk may not contain duplicate values.")
4045
+
4046
+ indx = np.argsort(np.ravel(xk))
4047
+ self.xk = np.take(np.ravel(xk), indx, 0)
4048
+ self.pk = np.take(np.ravel(pk), indx, 0)
4049
+ self.a = self.xk[0]
4050
+ self.b = self.xk[-1]
4051
+
4052
+ self.qvals = np.cumsum(self.pk, axis=0)
4053
+
4054
+ self.shapes = ' ' # bypass inspection
4055
+
4056
+ self._construct_argparser(meths_to_inspect=[self._pmf],
4057
+ locscale_in='loc=0',
4058
+ # scale=1 for discrete RVs
4059
+ locscale_out='loc, 1')
4060
+
4061
+ self._attach_methods()
4062
+
4063
+ self._construct_docstrings(name, longname)
4064
+
4065
+ def __getstate__(self):
4066
+ dct = self.__dict__.copy()
4067
+
4068
+ # these methods will be remade in rv_generic.__setstate__,
4069
+ # which calls rv_generic._attach_methods
4070
+ attrs = ["_parse_args", "_parse_args_stats", "_parse_args_rvs"]
4071
+ [dct.pop(attr, None) for attr in attrs]
4072
+
4073
+ return dct
4074
+
4075
+ def _attach_methods(self):
4076
+ """Attaches dynamically created argparser methods."""
4077
+ self._attach_argparser_methods()
4078
+
4079
+ def _get_support(self, *args):
4080
+ """Return the support of the (unscaled, unshifted) distribution.
4081
+
4082
+ Parameters
4083
+ ----------
4084
+ arg1, arg2, ... : array_like
4085
+ The shape parameter(s) for the distribution (see docstring of the
4086
+ instance object for more information).
4087
+
4088
+ Returns
4089
+ -------
4090
+ a, b : numeric (float, or int or +/-np.inf)
4091
+ end-points of the distribution's support.
4092
+ """
4093
+ return self.a, self.b
4094
+
4095
+ def _pmf(self, x):
4096
+ return np.select([x == k for k in self.xk],
4097
+ [np.broadcast_arrays(p, x)[0] for p in self.pk], 0)
4098
+
4099
+ def _cdf(self, x):
4100
+ xx, xxk = np.broadcast_arrays(x[:, None], self.xk)
4101
+ indx = np.argmax(xxk > xx, axis=-1) - 1
4102
+ return self.qvals[indx]
4103
+
4104
+ def _ppf(self, q):
4105
+ qq, sqq = np.broadcast_arrays(q[..., None], self.qvals)
4106
+ indx = argmax(sqq >= qq, axis=-1)
4107
+ return self.xk[indx]
4108
+
4109
+ def _rvs(self, size=None, random_state=None):
4110
+ # Need to define it explicitly, otherwise .rvs() with size=None
4111
+ # fails due to explicit broadcasting in _ppf
4112
+ U = random_state.uniform(size=size)
4113
+ if size is None:
4114
+ U = np.array(U, ndmin=1)
4115
+ Y = self._ppf(U)[0]
4116
+ else:
4117
+ Y = self._ppf(U)
4118
+ return Y
4119
+
4120
+ def _entropy(self):
4121
+ return stats.entropy(self.pk)
4122
+
4123
+ def generic_moment(self, n):
4124
+ n = asarray(n)
4125
+ return np.sum(self.xk**n[np.newaxis, ...] * self.pk, axis=0)
4126
+
4127
+ def _expect(self, fun, lb, ub, *args, **kwds):
4128
+ # ignore all args, just do a brute force summation
4129
+ supp = self.xk[(lb <= self.xk) & (self.xk <= ub)]
4130
+ vals = fun(supp)
4131
+ return np.sum(vals)
4132
+
4133
+
4134
+ def _check_shape(argshape, size):
4135
+ """
4136
+ This is a utility function used by `_rvs()` in the class geninvgauss_gen.
4137
+ It compares the tuple argshape to the tuple size.
4138
+
4139
+ Parameters
4140
+ ----------
4141
+ argshape : tuple of integers
4142
+ Shape of the arguments.
4143
+ size : tuple of integers or integer
4144
+ Size argument of rvs().
4145
+
4146
+ Returns
4147
+ -------
4148
+ The function returns two tuples, scalar_shape and bc.
4149
+
4150
+ scalar_shape : tuple
4151
+ Shape to which the 1-d array of random variates returned by
4152
+ _rvs_scalar() is converted when it is copied into the
4153
+ output array of _rvs().
4154
+
4155
+ bc : tuple of booleans
4156
+ bc is an tuple the same length as size. bc[j] is True if the data
4157
+ associated with that index is generated in one call of _rvs_scalar().
4158
+
4159
+ """
4160
+ scalar_shape = []
4161
+ bc = []
4162
+ for argdim, sizedim in zip_longest(argshape[::-1], size[::-1],
4163
+ fillvalue=1):
4164
+ if sizedim > argdim or (argdim == sizedim == 1):
4165
+ scalar_shape.append(sizedim)
4166
+ bc.append(True)
4167
+ else:
4168
+ bc.append(False)
4169
+ return tuple(scalar_shape[::-1]), tuple(bc[::-1])
4170
+
4171
+
4172
+ def get_distribution_names(namespace_pairs, rv_base_class):
4173
+ """Collect names of statistical distributions and their generators.
4174
+
4175
+ Parameters
4176
+ ----------
4177
+ namespace_pairs : sequence
4178
+ A snapshot of (name, value) pairs in the namespace of a module.
4179
+ rv_base_class : class
4180
+ The base class of random variable generator classes in a module.
4181
+
4182
+ Returns
4183
+ -------
4184
+ distn_names : list of strings
4185
+ Names of the statistical distributions.
4186
+ distn_gen_names : list of strings
4187
+ Names of the generators of the statistical distributions.
4188
+ Note that these are not simply the names of the statistical
4189
+ distributions, with a _gen suffix added.
4190
+
4191
+ """
4192
+ distn_names = []
4193
+ distn_gen_names = []
4194
+ for name, value in namespace_pairs:
4195
+ if name.startswith('_'):
4196
+ continue
4197
+ if name.endswith('_gen') and issubclass(value, rv_base_class):
4198
+ distn_gen_names.append(name)
4199
+ if isinstance(value, rv_base_class):
4200
+ distn_names.append(name)
4201
+ return distn_names, distn_gen_names