scipy 1.16.2__cp311-cp311-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.cp311-win_arm64.lib +0 -0
  4. scipy/_cyutility.cp311-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.cp311-win_arm64.lib +0 -0
  13. scipy/_lib/_ccallback_c.cp311-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.cp311-win_arm64.lib +0 -0
  18. scipy/_lib/_fpumode.cp311-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.cp311-win_arm64.lib +0 -0
  23. scipy/_lib/_test_ccallback.cp311-win_arm64.pyd +0 -0
  24. scipy/_lib/_test_deprecation_call.cp311-win_arm64.lib +0 -0
  25. scipy/_lib/_test_deprecation_call.cp311-win_arm64.pyd +0 -0
  26. scipy/_lib/_test_deprecation_def.cp311-win_arm64.lib +0 -0
  27. scipy/_lib/_test_deprecation_def.cp311-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.cp311-win_arm64.lib +0 -0
  35. scipy/_lib/_uarray/_uarray.cp311-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.cp311-win_arm64.lib +0 -0
  101. scipy/_lib/messagestream.cp311-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.cp311-win_arm64.lib +0 -0
  148. scipy/cluster/_hierarchy.cp311-win_arm64.pyd +0 -0
  149. scipy/cluster/_optimal_leaf_ordering.cp311-win_arm64.lib +0 -0
  150. scipy/cluster/_optimal_leaf_ordering.cp311-win_arm64.pyd +0 -0
  151. scipy/cluster/_vq.cp311-win_arm64.lib +0 -0
  152. scipy/cluster/_vq.cp311-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.cp311-win_arm64.lib +0 -0
  193. scipy/fft/_pocketfft/pypocketfft.cp311-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.cp311-win_arm64.lib +0 -0
  215. scipy/fftpack/convolve.cp311-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.cp311-win_arm64.lib +0 -0
  233. scipy/integrate/_dop.cp311-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.cp311-win_arm64.lib +0 -0
  248. scipy/integrate/_lsoda.cp311-win_arm64.pyd +0 -0
  249. scipy/integrate/_ode.py +1395 -0
  250. scipy/integrate/_odepack.cp311-win_arm64.lib +0 -0
  251. scipy/integrate/_odepack.cp311-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.cp311-win_arm64.lib +0 -0
  255. scipy/integrate/_quadpack.cp311-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.cp311-win_arm64.lib +0 -0
  265. scipy/integrate/_test_multivariate.cp311-win_arm64.pyd +0 -0
  266. scipy/integrate/_test_odeint_banded.cp311-win_arm64.lib +0 -0
  267. scipy/integrate/_test_odeint_banded.cp311-win_arm64.pyd +0 -0
  268. scipy/integrate/_vode.cp311-win_arm64.lib +0 -0
  269. scipy/integrate/_vode.cp311-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.cp311-win_arm64.lib +0 -0
  290. scipy/interpolate/_dfitpack.cp311-win_arm64.pyd +0 -0
  291. scipy/interpolate/_dierckx.cp311-win_arm64.lib +0 -0
  292. scipy/interpolate/_dierckx.cp311-win_arm64.pyd +0 -0
  293. scipy/interpolate/_fitpack.cp311-win_arm64.lib +0 -0
  294. scipy/interpolate/_fitpack.cp311-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.cp311-win_arm64.lib +0 -0
  300. scipy/interpolate/_interpnd.cp311-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.cp311-win_arm64.lib +0 -0
  307. scipy/interpolate/_ppoly.cp311-win_arm64.pyd +0 -0
  308. scipy/interpolate/_rbf.py +290 -0
  309. scipy/interpolate/_rbfinterp.py +550 -0
  310. scipy/interpolate/_rbfinterp_pythran.cp311-win_arm64.lib +0 -0
  311. scipy/interpolate/_rbfinterp_pythran.cp311-win_arm64.pyd +0 -0
  312. scipy/interpolate/_rgi.py +764 -0
  313. scipy/interpolate/_rgi_cython.cp311-win_arm64.lib +0 -0
  314. scipy/interpolate/_rgi_cython.cp311-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.cp311-win_arm64.lib +0 -0
  343. scipy/io/_fast_matrix_market/_fmm_core.cp311-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.cp311-win_arm64.lib +0 -0
  355. scipy/io/_test_fortran.cp311-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.cp311-win_arm64.lib +0 -0
  386. scipy/io/matlab/_mio5_utils.cp311-win_arm64.pyd +0 -0
  387. scipy/io/matlab/_mio_utils.cp311-win_arm64.lib +0 -0
  388. scipy/io/matlab/_mio_utils.cp311-win_arm64.pyd +0 -0
  389. scipy/io/matlab/_miobase.py +435 -0
  390. scipy/io/matlab/_streams.cp311-win_arm64.lib +0 -0
  391. scipy/io/matlab/_streams.cp311-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.cp311-win_arm64.lib +0 -0
  623. scipy/linalg/_cythonized_array_utils.cp311-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.cp311-win_arm64.lib +0 -0
  630. scipy/linalg/_decomp_interpolative.cp311-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.cp311-win_arm64.lib +0 -0
  634. scipy/linalg/_decomp_lu_cython.cp311-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.cp311-win_arm64.lib +0 -0
  642. scipy/linalg/_decomp_update.cp311-win_arm64.pyd +0 -0
  643. scipy/linalg/_expm_frechet.py +417 -0
  644. scipy/linalg/_fblas.cp311-win_arm64.lib +0 -0
  645. scipy/linalg/_fblas.cp311-win_arm64.pyd +0 -0
  646. scipy/linalg/_flapack.cp311-win_arm64.lib +0 -0
  647. scipy/linalg/_flapack.cp311-win_arm64.pyd +0 -0
  648. scipy/linalg/_lapack_subroutines.h +1521 -0
  649. scipy/linalg/_linalg_pythran.cp311-win_arm64.lib +0 -0
  650. scipy/linalg/_linalg_pythran.cp311-win_arm64.pyd +0 -0
  651. scipy/linalg/_matfuncs.py +1050 -0
  652. scipy/linalg/_matfuncs_expm.cp311-win_arm64.lib +0 -0
  653. scipy/linalg/_matfuncs_expm.cp311-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.cp311-win_arm64.lib +0 -0
  657. scipy/linalg/_matfuncs_schur_sqrtm.cp311-win_arm64.pyd +0 -0
  658. scipy/linalg/_matfuncs_sqrtm.py +107 -0
  659. scipy/linalg/_matfuncs_sqrtm_triu.cp311-win_arm64.lib +0 -0
  660. scipy/linalg/_matfuncs_sqrtm_triu.cp311-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.cp311-win_arm64.lib +0 -0
  665. scipy/linalg/_solve_toeplitz.cp311-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.cp311-win_arm64.lib +0 -0
  672. scipy/linalg/cython_blas.cp311-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.cp311-win_arm64.lib +0 -0
  676. scipy/linalg/cython_lapack.cp311-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.cp311-win_arm64.lib +0 -0
  728. scipy/ndimage/_ctest.cp311-win_arm64.pyd +0 -0
  729. scipy/ndimage/_cytest.cp311-win_arm64.lib +0 -0
  730. scipy/ndimage/_cytest.cp311-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.cp311-win_arm64.lib +0 -0
  738. scipy/ndimage/_nd_image.cp311-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.cp311-win_arm64.lib +0 -0
  742. scipy/ndimage/_ni_label.cp311-win_arm64.pyd +0 -0
  743. scipy/ndimage/_ni_support.py +139 -0
  744. scipy/ndimage/_rank_filter_1d.cp311-win_arm64.lib +0 -0
  745. scipy/ndimage/_rank_filter_1d.cp311-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.cp311-win_arm64.lib +0 -0
  768. scipy/odr/__odrpack.cp311-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.cp311-win_arm64.lib +0 -0
  780. scipy/optimize/_bglu_dense.cp311-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.cp311-win_arm64.lib +0 -0
  790. scipy/optimize/_direct.cp311-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.cp311-win_arm64.lib +0 -0
  795. scipy/optimize/_group_columns.cp311-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.cp311-win_arm64.lib +0 -0
  799. scipy/optimize/_highspy/_core.cp311-win_arm64.pyd +0 -0
  800. scipy/optimize/_highspy/_highs_options.cp311-win_arm64.lib +0 -0
  801. scipy/optimize/_highspy/_highs_options.cp311-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.cp311-win_arm64.lib +0 -0
  805. scipy/optimize/_lbfgsb.cp311-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.cp311-win_arm64.lib +0 -0
  816. scipy/optimize/_lsap.cp311-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.cp311-win_arm64.lib +0 -0
  822. scipy/optimize/_lsq/givens_elimination.cp311-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.cp311-win_arm64.lib +0 -0
  830. scipy/optimize/_minpack.cp311-win_arm64.pyd +0 -0
  831. scipy/optimize/_minpack_py.py +1178 -0
  832. scipy/optimize/_moduleTNC.cp311-win_arm64.lib +0 -0
  833. scipy/optimize/_moduleTNC.cp311-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.cp311-win_arm64.lib +0 -0
  839. scipy/optimize/_pava_pybind.cp311-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.cp311-win_arm64.lib +0 -0
  850. scipy/optimize/_slsqplib.cp311-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.cp311-win_arm64.lib +0 -0
  855. scipy/optimize/_trlib/_trlib.cp311-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.cp311-win_arm64.lib +0 -0
  877. scipy/optimize/_zeros.cp311-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.cp311-win_arm64.lib +0 -0
  882. scipy/optimize/cython_optimize/_zeros.cp311-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.cp311-win_arm64.lib +0 -0
  953. scipy/signal/_max_len_seq_inner.cp311-win_arm64.pyd +0 -0
  954. scipy/signal/_peak_finding.py +1310 -0
  955. scipy/signal/_peak_finding_utils.cp311-win_arm64.lib +0 -0
  956. scipy/signal/_peak_finding_utils.cp311-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.cp311-win_arm64.lib +0 -0
  963. scipy/signal/_sigtools.cp311-win_arm64.pyd +0 -0
  964. scipy/signal/_sosfilt.cp311-win_arm64.lib +0 -0
  965. scipy/signal/_sosfilt.cp311-win_arm64.pyd +0 -0
  966. scipy/signal/_spectral_py.py +2471 -0
  967. scipy/signal/_spline.cp311-win_arm64.lib +0 -0
  968. scipy/signal/_spline.cp311-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.cp311-win_arm64.lib +0 -0
  974. scipy/signal/_upfirdn_apply.cp311-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.cp311-win_arm64.lib +0 -0
  1021. scipy/sparse/_csparsetools.cp311-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.cp311-win_arm64.lib +0 -0
  1032. scipy/sparse/_sparsetools.cp311-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.cp311-win_arm64.lib +0 -0
  1043. scipy/sparse/csgraph/_flow.cp311-win_arm64.pyd +0 -0
  1044. scipy/sparse/csgraph/_laplacian.py +563 -0
  1045. scipy/sparse/csgraph/_matching.cp311-win_arm64.lib +0 -0
  1046. scipy/sparse/csgraph/_matching.cp311-win_arm64.pyd +0 -0
  1047. scipy/sparse/csgraph/_min_spanning_tree.cp311-win_arm64.lib +0 -0
  1048. scipy/sparse/csgraph/_min_spanning_tree.cp311-win_arm64.pyd +0 -0
  1049. scipy/sparse/csgraph/_reordering.cp311-win_arm64.lib +0 -0
  1050. scipy/sparse/csgraph/_reordering.cp311-win_arm64.pyd +0 -0
  1051. scipy/sparse/csgraph/_shortest_path.cp311-win_arm64.lib +0 -0
  1052. scipy/sparse/csgraph/_shortest_path.cp311-win_arm64.pyd +0 -0
  1053. scipy/sparse/csgraph/_tools.cp311-win_arm64.lib +0 -0
  1054. scipy/sparse/csgraph/_tools.cp311-win_arm64.pyd +0 -0
  1055. scipy/sparse/csgraph/_traversal.cp311-win_arm64.lib +0 -0
  1056. scipy/sparse/csgraph/_traversal.cp311-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.cp311-win_arm64.lib +0 -0
  1079. scipy/sparse/linalg/_dsolve/_superlu.cp311-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.cp311-win_arm64.lib +0 -0
  1089. scipy/sparse/linalg/_eigen/arpack/_arpack.cp311-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.cp311-win_arm64.lib +0 -0
  1122. scipy/sparse/linalg/_propack/_cpropack.cp311-win_arm64.pyd +0 -0
  1123. scipy/sparse/linalg/_propack/_dpropack.cp311-win_arm64.lib +0 -0
  1124. scipy/sparse/linalg/_propack/_dpropack.cp311-win_arm64.pyd +0 -0
  1125. scipy/sparse/linalg/_propack/_spropack.cp311-win_arm64.lib +0 -0
  1126. scipy/sparse/linalg/_propack/_spropack.cp311-win_arm64.pyd +0 -0
  1127. scipy/sparse/linalg/_propack/_zpropack.cp311-win_arm64.lib +0 -0
  1128. scipy/sparse/linalg/_propack/_zpropack.cp311-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.cp311-win_arm64.lib +0 -0
  1170. scipy/spatial/_ckdtree.cp311-win_arm64.pyd +0 -0
  1171. scipy/spatial/_distance_pybind.cp311-win_arm64.lib +0 -0
  1172. scipy/spatial/_distance_pybind.cp311-win_arm64.pyd +0 -0
  1173. scipy/spatial/_distance_wrap.cp311-win_arm64.lib +0 -0
  1174. scipy/spatial/_distance_wrap.cp311-win_arm64.pyd +0 -0
  1175. scipy/spatial/_geometric_slerp.py +238 -0
  1176. scipy/spatial/_hausdorff.cp311-win_arm64.lib +0 -0
  1177. scipy/spatial/_hausdorff.cp311-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.cp311-win_arm64.lib +0 -0
  1182. scipy/spatial/_qhull.cp311-win_arm64.pyd +0 -0
  1183. scipy/spatial/_qhull.pyi +213 -0
  1184. scipy/spatial/_spherical_voronoi.py +341 -0
  1185. scipy/spatial/_voronoi.cp311-win_arm64.lib +0 -0
  1186. scipy/spatial/_voronoi.cp311-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.cp311-win_arm64.lib +0 -0
  1236. scipy/spatial/transform/_rigid_transform.cp311-win_arm64.pyd +0 -0
  1237. scipy/spatial/transform/_rotation.cp311-win_arm64.lib +0 -0
  1238. scipy/spatial/transform/_rotation.cp311-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.cp311-win_arm64.lib +0 -0
  1252. scipy/special/_comb.cp311-win_arm64.pyd +0 -0
  1253. scipy/special/_ellip_harm.py +214 -0
  1254. scipy/special/_ellip_harm_2.cp311-win_arm64.lib +0 -0
  1255. scipy/special/_ellip_harm_2.cp311-win_arm64.pyd +0 -0
  1256. scipy/special/_gufuncs.cp311-win_arm64.lib +0 -0
  1257. scipy/special/_gufuncs.cp311-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.cp311-win_arm64.lib +0 -0
  1281. scipy/special/_specfun.cp311-win_arm64.pyd +0 -0
  1282. scipy/special/_special_ufuncs.cp311-win_arm64.lib +0 -0
  1283. scipy/special/_special_ufuncs.cp311-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.cp311-win_arm64.lib +0 -0
  1288. scipy/special/_test_internal.cp311-win_arm64.pyd +0 -0
  1289. scipy/special/_test_internal.pyi +9 -0
  1290. scipy/special/_testutils.py +321 -0
  1291. scipy/special/_ufuncs.cp311-win_arm64.lib +0 -0
  1292. scipy/special/_ufuncs.cp311-win_arm64.pyd +0 -0
  1293. scipy/special/_ufuncs.pyi +522 -0
  1294. scipy/special/_ufuncs.pyx +13173 -0
  1295. scipy/special/_ufuncs_cxx.cp311-win_arm64.lib +0 -0
  1296. scipy/special/_ufuncs_cxx.cp311-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.cp311-win_arm64.lib +0 -0
  1304. scipy/special/cython_special.cp311-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.cp311-win_arm64.lib +0 -0
  1376. scipy/stats/_ansari_swilk_statistics.cp311-win_arm64.pyd +0 -0
  1377. scipy/stats/_axis_nan_policy.py +692 -0
  1378. scipy/stats/_biasedurn.cp311-win_arm64.lib +0 -0
  1379. scipy/stats/_biasedurn.cp311-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.cp311-win_arm64.lib +0 -0
  1404. scipy/stats/_levy_stable/levyst.cp311-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.cp311-win_arm64.lib +0 -0
  1418. scipy/stats/_qmc_cy.cp311-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.cp311-win_arm64.lib +0 -0
  1422. scipy/stats/_qmvnt_cy.cp311-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.cp311-win_arm64.lib +0 -0
  1426. scipy/stats/_rcont/rcont.cp311-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.cp311-win_arm64.lib +0 -0
  1433. scipy/stats/_sobol.cp311-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.cp311-win_arm64.lib +0 -0
  1437. scipy/stats/_stats.cp311-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.cp311-win_arm64.lib +0 -0
  1442. scipy/stats/_stats_pythran.cp311-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.cp311-win_arm64.lib +0 -0
  1447. scipy/stats/_unuran/unuran_wrapper.cp311-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,2198 @@
1
+ import itertools as it
2
+ import os
3
+ import pickle
4
+ from copy import deepcopy
5
+
6
+ import numpy as np
7
+ from numpy import inf
8
+ import pytest
9
+ from numpy.testing import assert_allclose, assert_equal
10
+ from hypothesis import strategies, given, reproduce_failure, settings # noqa: F401
11
+ import hypothesis.extra.numpy as npst
12
+
13
+ from scipy import special
14
+ from scipy import stats
15
+ from scipy.stats._fit import _kolmogorov_smirnov
16
+ from scipy.stats._ksstats import kolmogn
17
+ from scipy.stats import qmc
18
+ from scipy.stats._distr_params import distcont, distdiscrete
19
+ from scipy.stats._distribution_infrastructure import (
20
+ _Domain, _RealInterval, _Parameter, _Parameterization, _RealParameter,
21
+ ContinuousDistribution, ShiftedScaledDistribution, _fiinfo,
22
+ _generate_domain_support, Mixture)
23
+ from scipy.stats._new_distributions import StandardNormal, _LogUniform, _Gamma
24
+ from scipy.stats._new_distributions import DiscreteDistribution
25
+ from scipy.stats import Normal, Uniform, Binomial
26
+
27
+
28
+ class Test_RealInterval:
29
+ rng = np.random.default_rng(349849812549824)
30
+
31
+ def test_iv(self):
32
+ domain = _RealInterval(endpoints=('a', 'b'))
33
+ message = "The endpoints of the distribution are defined..."
34
+ with pytest.raises(TypeError, match=message):
35
+ domain.get_numerical_endpoints(dict)
36
+
37
+
38
+ @pytest.mark.parametrize('x', [rng.uniform(10, 10, size=(2, 3, 4)),
39
+ -np.inf, np.pi])
40
+ def test_contains_simple(self, x):
41
+ # Test `contains` when endpoints are defined by constants
42
+ a, b = -np.inf, np.pi
43
+ domain = _RealInterval(endpoints=(a, b), inclusive=(False, True))
44
+ assert_equal(domain.contains(x), (a < x) & (x <= b))
45
+
46
+ @pytest.mark.slow
47
+ @given(shapes=npst.mutually_broadcastable_shapes(num_shapes=3, min_side=0),
48
+ inclusive_a=strategies.booleans(),
49
+ inclusive_b=strategies.booleans(),
50
+ data=strategies.data())
51
+ @pytest.mark.thread_unsafe
52
+ def test_contains(self, shapes, inclusive_a, inclusive_b, data):
53
+ # Test `contains` when endpoints are defined by parameters
54
+ input_shapes, result_shape = shapes
55
+ shape_a, shape_b, shape_x = input_shapes
56
+
57
+ # Without defining min and max values, I spent forever trying to set
58
+ # up a valid test without overflows or similar just drawing arrays.
59
+ a_elements = dict(allow_nan=False, allow_infinity=False,
60
+ min_value=-1e3, max_value=1)
61
+ b_elements = dict(allow_nan=False, allow_infinity=False,
62
+ min_value=2, max_value=1e3)
63
+ a = data.draw(npst.arrays(npst.floating_dtypes(),
64
+ shape_a, elements=a_elements))
65
+ b = data.draw(npst.arrays(npst.floating_dtypes(),
66
+ shape_b, elements=b_elements))
67
+ # ensure some points are to the left, some to the right, and some
68
+ # are exactly on the boundary
69
+ d = b - a
70
+ x = np.concatenate([np.linspace(a-d, a, 10),
71
+ np.linspace(a, b, 10),
72
+ np.linspace(b, b+d, 10)])
73
+ # Domain is defined by two parameters, 'a' and 'b'
74
+ domain = _RealInterval(endpoints=('a', 'b'),
75
+ inclusive=(inclusive_a, inclusive_b))
76
+ domain.define_parameters(_RealParameter('a', domain=_RealInterval()),
77
+ _RealParameter('b', domain=_RealInterval()))
78
+ # Check that domain and string evaluation give the same result
79
+ res = domain.contains(x, dict(a=a, b=b))
80
+
81
+ # Apparently, `np.float16([2]) < np.float32(2.0009766)` is False
82
+ # but `np.float16([2]) < np.float32([2.0009766])` is True
83
+ # dtype = np.result_type(a.dtype, b.dtype, x.dtype)
84
+ # a, b, x = a.astype(dtype), b.astype(dtype), x.astype(dtype)
85
+ # unclear whether we should be careful about this, since it will be
86
+ # fixed with NEP50. Just do what makes the test pass.
87
+ left_comparison = '<=' if inclusive_a else '<'
88
+ right_comparison = '<=' if inclusive_b else '<'
89
+ ref = eval(f'(a {left_comparison} x) & (x {right_comparison} b)')
90
+ assert_equal(res, ref)
91
+
92
+ @pytest.mark.parametrize("inclusive", list(it.product([True, False], repeat=2)))
93
+ @pytest.mark.parametrize("a,b", [(0, 1), (3, 1)])
94
+ def test_contains_function_endpoints(self, inclusive, a, b):
95
+ # Test `contains` when endpoints are defined by functions.
96
+ endpoints = (lambda a, b: (a - b) / 2, lambda a, b: (a + b) / 2)
97
+ domain = _RealInterval(endpoints=endpoints, inclusive=inclusive)
98
+ x = np.asarray([(a - 2*b)/2, (a - b)/2, a/2, (a + b)/2, (a + 2*b)/2])
99
+ res = domain.contains(x, dict(a=a, b=b))
100
+
101
+ numerical_endpoints = ((a - b) / 2, (a + b) / 2)
102
+ assert numerical_endpoints == domain.get_numerical_endpoints(dict(a=a, b=b))
103
+ alpha, beta = numerical_endpoints
104
+
105
+ above_left = alpha <= x if inclusive[0] else alpha < x
106
+ below_right = x <= beta if inclusive[1] else x < beta
107
+ ref = above_left & below_right
108
+ assert_equal(res, ref)
109
+
110
+
111
+ @pytest.mark.parametrize('case', [
112
+ (-np.inf, np.pi, False, True, r"(-\infty, \pi]"),
113
+ ('a', 5, True, False, "[a, 5)")
114
+ ])
115
+ def test_str(self, case):
116
+ domain = _RealInterval(endpoints=case[:2], inclusive=case[2:4])
117
+ assert str(domain) == case[4]
118
+
119
+ @pytest.mark.slow
120
+ @given(a=strategies.one_of(
121
+ strategies.decimals(allow_nan=False),
122
+ strategies.characters(whitelist_categories="L"), # type: ignore[arg-type]
123
+ strategies.sampled_from(list(_Domain.symbols))),
124
+ b=strategies.one_of(
125
+ strategies.decimals(allow_nan=False),
126
+ strategies.characters(whitelist_categories="L"), # type: ignore[arg-type]
127
+ strategies.sampled_from(list(_Domain.symbols))),
128
+ inclusive_a=strategies.booleans(),
129
+ inclusive_b=strategies.booleans(),
130
+ )
131
+ @pytest.mark.thread_unsafe
132
+ def test_str2(self, a, b, inclusive_a, inclusive_b):
133
+ # I wrote this independently from the implementation of __str__, but
134
+ # I imagine it looks pretty similar to __str__.
135
+ a = _Domain.symbols.get(a, a)
136
+ b = _Domain.symbols.get(b, b)
137
+ left_bracket = '[' if inclusive_a else '('
138
+ right_bracket = ']' if inclusive_b else ')'
139
+ domain = _RealInterval(endpoints=(a, b),
140
+ inclusive=(inclusive_a, inclusive_b))
141
+ ref = f"{left_bracket}{a}, {b}{right_bracket}"
142
+ assert str(domain) == ref
143
+
144
+ def test_symbols_gh22137(self):
145
+ # `symbols` was accidentally shared between instances originally
146
+ # Check that this is no longer the case
147
+ domain1 = _RealInterval(endpoints=(0, 1))
148
+ domain2 = _RealInterval(endpoints=(0, 1))
149
+ assert domain1.symbols is not domain2.symbols
150
+
151
+
152
+ def draw_distribution_from_family(family, data, rng, proportions, min_side=0):
153
+ # If the distribution has parameters, choose a parameterization and
154
+ # draw broadcastable shapes for the parameter arrays.
155
+ n_parameterizations = family._num_parameterizations()
156
+ if n_parameterizations > 0:
157
+ i = data.draw(strategies.integers(0, max_value=n_parameterizations-1))
158
+ n_parameters = family._num_parameters(i)
159
+ shapes, result_shape = data.draw(
160
+ npst.mutually_broadcastable_shapes(num_shapes=n_parameters,
161
+ min_side=min_side))
162
+ dist = family._draw(shapes, rng=rng, proportions=proportions,
163
+ i_parameterization=i)
164
+ else:
165
+ dist = family._draw(rng=rng)
166
+ result_shape = tuple()
167
+
168
+ # Draw a broadcastable shape for the arguments, and draw values for the
169
+ # arguments.
170
+ x_shape = data.draw(npst.broadcastable_shapes(result_shape,
171
+ min_side=min_side))
172
+ x = dist._variable.draw(x_shape, parameter_values=dist._parameters,
173
+ proportions=proportions, rng=rng, region='typical')
174
+ x_result_shape = np.broadcast_shapes(x_shape, result_shape)
175
+ y_shape = data.draw(npst.broadcastable_shapes(x_result_shape,
176
+ min_side=min_side))
177
+ y = dist._variable.draw(y_shape, parameter_values=dist._parameters,
178
+ proportions=proportions, rng=rng, region='typical')
179
+ xy_result_shape = np.broadcast_shapes(y_shape, x_result_shape)
180
+ p_domain = _RealInterval((0, 1), (True, True))
181
+ p_var = _RealParameter('p', domain=p_domain)
182
+ p = p_var.draw(x_shape, proportions=proportions, rng=rng)
183
+ with np.errstate(divide='ignore', invalid='ignore'):
184
+ logp = np.log(p)
185
+
186
+ return dist, x, y, p, logp, result_shape, x_result_shape, xy_result_shape
187
+
188
+
189
+ continuous_families = [
190
+ StandardNormal,
191
+ Normal,
192
+ Uniform,
193
+ _LogUniform
194
+ ]
195
+
196
+ discrete_families = [
197
+ Binomial,
198
+ ]
199
+
200
+ families = continuous_families + discrete_families
201
+
202
+
203
+ class TestDistributions:
204
+ @pytest.mark.fail_slow(60) # need to break up check_moment_funcs
205
+ @settings(max_examples=20)
206
+ @pytest.mark.parametrize('family', families)
207
+ @given(data=strategies.data(), seed=strategies.integers(min_value=0))
208
+ @pytest.mark.thread_unsafe
209
+ def test_support_moments_sample(self, family, data, seed):
210
+ rng = np.random.default_rng(seed)
211
+
212
+ # relative proportions of valid, endpoint, out of bounds, and NaN params
213
+ proportions = (0.7, 0.1, 0.1, 0.1)
214
+ tmp = draw_distribution_from_family(family, data, rng, proportions)
215
+ dist, x, y, p, logp, result_shape, x_result_shape, xy_result_shape = tmp
216
+ sample_shape = data.draw(npst.array_shapes(min_dims=0, min_side=0,
217
+ max_side=20))
218
+
219
+ with np.errstate(invalid='ignore', divide='ignore'):
220
+ check_support(dist)
221
+ check_moment_funcs(dist, result_shape) # this needs to get split up
222
+ check_sample_shape_NaNs(dist, 'sample', sample_shape, result_shape, rng)
223
+ qrng = qmc.Halton(d=1, seed=rng)
224
+ check_sample_shape_NaNs(dist, 'sample', sample_shape, result_shape, qrng)
225
+
226
+ @pytest.mark.fail_slow(10)
227
+ @pytest.mark.parametrize('family', families)
228
+ @pytest.mark.parametrize('func, methods, arg',
229
+ [('entropy', {'log/exp', 'quadrature'}, None),
230
+ ('logentropy', {'log/exp', 'quadrature'}, None),
231
+ ('median', {'icdf'}, None),
232
+ ('mode', {'optimization'}, None),
233
+ ('mean', {'cache'}, None),
234
+ ('variance', {'cache'}, None),
235
+ ('skewness', {'cache'}, None),
236
+ ('kurtosis', {'cache'}, None),
237
+ ('pdf', {'log/exp'}, 'x'),
238
+ ('logpdf', {'log/exp'}, 'x'),
239
+ ('logcdf', {'log/exp', 'complement', 'quadrature'}, 'x'),
240
+ ('cdf', {'log/exp', 'complement', 'quadrature'}, 'x'),
241
+ ('logccdf', {'log/exp', 'complement', 'quadrature'}, 'x'),
242
+ ('ccdf', {'log/exp', 'complement', 'quadrature'}, 'x'),
243
+ ('ilogccdf', {'complement', 'inversion'}, 'logp'),
244
+ ('iccdf', {'complement', 'inversion'}, 'p'),
245
+ ])
246
+ @settings(max_examples=20)
247
+ @given(data=strategies.data(), seed=strategies.integers(min_value=0))
248
+ @pytest.mark.thread_unsafe
249
+ def test_funcs(self, family, data, seed, func, methods, arg):
250
+ if family == Uniform and func == 'mode':
251
+ pytest.skip("Mode is not unique; `method`s disagree.")
252
+
253
+ rng = np.random.default_rng(seed)
254
+
255
+ # relative proportions of valid, endpoint, out of bounds, and NaN params
256
+ proportions = (0.7, 0.1, 0.1, 0.1)
257
+ tmp = draw_distribution_from_family(family, data, rng, proportions)
258
+ dist, x, y, p, logp, result_shape, x_result_shape, xy_result_shape = tmp
259
+
260
+ args = {'x': x, 'p': p, 'logp': p}
261
+ with np.errstate(invalid='ignore', divide='ignore', over='ignore'):
262
+ if arg is None:
263
+ check_dist_func(dist, func, None, result_shape, methods)
264
+ elif arg in args:
265
+ check_dist_func(dist, func, args[arg], x_result_shape, methods)
266
+
267
+ if func == 'variance':
268
+ assert_allclose(dist.standard_deviation()**2, dist.variance())
269
+
270
+ # invalid and divide are to be expected; maybe look into over
271
+ with np.errstate(invalid='ignore', divide='ignore', over='ignore'):
272
+ if not isinstance(dist, ShiftedScaledDistribution):
273
+ if func == 'cdf':
274
+ methods = {'quadrature'}
275
+ check_cdf2(dist, False, x, y, xy_result_shape, methods)
276
+ check_cdf2(dist, True, x, y, xy_result_shape, methods)
277
+ elif func == 'ccdf':
278
+ methods = {'addition'}
279
+ check_ccdf2(dist, False, x, y, xy_result_shape, methods)
280
+ check_ccdf2(dist, True, x, y, xy_result_shape, methods)
281
+
282
+ @pytest.mark.thread_unsafe
283
+ def test_plot(self):
284
+ try:
285
+ import matplotlib.pyplot as plt
286
+ except ImportError:
287
+ return
288
+
289
+ X = Uniform(a=0., b=1.)
290
+ ax = X.plot()
291
+ assert ax == plt.gca()
292
+
293
+ @pytest.mark.parametrize('method_name', ['cdf', 'ccdf'])
294
+ def test_complement_safe(self, method_name):
295
+ X = stats.Normal()
296
+ X.tol = 1e-12
297
+ p = np.asarray([1e-4, 1e-3])
298
+ func = getattr(X, method_name)
299
+ ifunc = getattr(X, 'i'+method_name)
300
+ x = ifunc(p, method='formula')
301
+ p1 = func(x, method='complement_safe')
302
+ p2 = func(x, method='complement')
303
+ assert_equal(p1[1], p2[1])
304
+ assert p1[0] != p2[0]
305
+ assert_allclose(p1[0], p[0], rtol=X.tol)
306
+
307
+ @pytest.mark.parametrize('method_name', ['cdf', 'ccdf'])
308
+ def test_icomplement_safe(self, method_name):
309
+ X = stats.Normal()
310
+ X.tol = 1e-12
311
+ p = np.asarray([1e-4, 1e-3])
312
+ func = getattr(X, method_name)
313
+ ifunc = getattr(X, 'i'+method_name)
314
+ x1 = ifunc(p, method='complement_safe')
315
+ x2 = ifunc(p, method='complement')
316
+ assert_equal(x1[1], x2[1])
317
+ assert x1[0] != x2[0]
318
+ assert_allclose(func(x1[0]), p[0], rtol=X.tol)
319
+
320
+ def test_subtraction_safe(self):
321
+ X = stats.Normal()
322
+ X.tol = 1e-12
323
+
324
+ # Regular subtraction is fine in either tail (and of course, across tails)
325
+ x = [-11, -10, 10, 11]
326
+ y = [-10, -11, 11, 10]
327
+ p0 = X.cdf(x, y, method='quadrature')
328
+ p1 = X.cdf(x, y, method='subtraction_safe')
329
+ p2 = X.cdf(x, y, method='subtraction')
330
+ assert_equal(p2, p1)
331
+ assert_allclose(p1, p0, rtol=X.tol)
332
+
333
+ # Safe subtraction is needed in special cases
334
+ x = np.asarray([-1e-20, -1e-21, 1e-20, 1e-21, -1e-20])
335
+ y = np.asarray([-1e-21, -1e-20, 1e-21, 1e-20, 1e-20])
336
+
337
+
338
+ p0 = X.pdf(0)*(y-x)
339
+ p1 = X.cdf(x, y, method='subtraction_safe')
340
+ p2 = X.cdf(x, y, method='subtraction')
341
+ assert_equal(p2, 0)
342
+ assert_allclose(p1, p0, rtol=X.tol)
343
+
344
+ def test_logentropy_safe(self):
345
+ # simulate an `entropy` calculation over/underflowing with extreme parameters
346
+ class _Normal(stats.Normal):
347
+ def _entropy_formula(self, **params):
348
+ out = np.asarray(super()._entropy_formula(**params))
349
+ out[0] = 0
350
+ out[-1] = np.inf
351
+ return out
352
+
353
+ X = _Normal(sigma=[1, 2, 3])
354
+ with np.errstate(divide='ignore'):
355
+ res1 = X.logentropy(method='logexp_safe')
356
+ res2 = X.logentropy(method='logexp')
357
+ ref = X.logentropy(method='quadrature')
358
+ i_fl = [0, -1] # first and last
359
+ assert np.isinf(res2[i_fl]).all()
360
+ assert res1[1] == res2[1]
361
+ # quadrature happens to be perfectly accurate on some platforms
362
+ # assert res1[1] != ref[1]
363
+ assert_equal(res1[i_fl], ref[i_fl])
364
+
365
+ def test_logcdf2_safe(self):
366
+ # test what happens when 2-arg `cdf` underflows
367
+ X = stats.Normal(sigma=[1, 2, 3])
368
+ x = [-301, 1, 300]
369
+ y = [-300, 2, 301]
370
+ with np.errstate(divide='ignore'):
371
+ res1 = X.logcdf(x, y, method='logexp_safe')
372
+ res2 = X.logcdf(x, y, method='logexp')
373
+ ref = X.logcdf(x, y, method='quadrature')
374
+ i_fl = [0, -1] # first and last
375
+ assert np.isinf(res2[i_fl]).all()
376
+ assert res1[1] == res2[1]
377
+ # quadrature happens to be perfectly accurate on some platforms
378
+ # assert res1[1] != ref[1]
379
+ assert_equal(res1[i_fl], ref[i_fl])
380
+
381
+ @pytest.mark.parametrize('method_name', ['logcdf', 'logccdf'])
382
+ def test_logexp_safe(self, method_name):
383
+ # test what happens when `cdf`/`ccdf` underflows
384
+ X = stats.Normal(sigma=2)
385
+ x = [-301, 1] if method_name == 'logcdf' else [301, 1]
386
+ func = getattr(X, method_name)
387
+ with np.errstate(divide='ignore'):
388
+ res1 = func(x, method='logexp_safe')
389
+ res2 = func(x, method='logexp')
390
+ ref = func(x, method='quadrature')
391
+ assert res1[0] == ref[0]
392
+ assert res1[0] != res2[0]
393
+ assert res1[1] == res2[1]
394
+ assert res1[1] != ref[1]
395
+
396
+ def check_sample_shape_NaNs(dist, fname, sample_shape, result_shape, rng):
397
+ full_shape = sample_shape + result_shape
398
+ if fname == 'sample':
399
+ sample_method = dist.sample
400
+
401
+ methods = {'inverse_transform'}
402
+ if dist._overrides(f'_{fname}_formula') and not isinstance(rng, qmc.QMCEngine):
403
+ methods.add('formula')
404
+
405
+ for method in methods:
406
+ res = sample_method(sample_shape, method=method, rng=rng)
407
+ valid_parameters = np.broadcast_to(get_valid_parameters(dist),
408
+ res.shape)
409
+ assert_equal(res.shape, full_shape)
410
+ np.testing.assert_equal(res.dtype, dist._dtype)
411
+
412
+ if full_shape == ():
413
+ # NumPy random makes a distinction between a 0d array and a scalar.
414
+ # In stats, we consistently turn 0d arrays into scalars, so
415
+ # maintain that behavior here. (With Array API arrays, this will
416
+ # change.)
417
+ assert np.isscalar(res)
418
+ assert np.all(np.isfinite(res[valid_parameters]))
419
+ assert_equal(res[~valid_parameters], np.nan)
420
+
421
+ sample1 = sample_method(sample_shape, method=method, rng=42)
422
+ sample2 = sample_method(sample_shape, method=method, rng=42)
423
+ if not isinstance(dist, DiscreteDistribution):
424
+ # The idea is that it's very unlikely that the random sample
425
+ # for a randomly chosen seed will match that for seed 42,
426
+ # but it is not so unlikely if `dist` is a discrete distribution.
427
+ assert not np.any(np.equal(res, sample1))
428
+ assert_equal(sample1, sample2)
429
+
430
+
431
+ def check_support(dist):
432
+ a, b = dist.support()
433
+ check_nans_and_edges(dist, 'support', None, a)
434
+ check_nans_and_edges(dist, 'support', None, b)
435
+ assert a.shape == dist._shape
436
+ assert b.shape == dist._shape
437
+ assert a.dtype == dist._dtype
438
+ assert b.dtype == dist._dtype
439
+
440
+
441
+ def check_dist_func(dist, fname, arg, result_shape, methods):
442
+ # Check that all computation methods of all distribution functions agree
443
+ # with one another, effectively testing the correctness of the generic
444
+ # computation methods and confirming the consistency of specific
445
+ # distributions with their pdf/logpdf.
446
+
447
+ args = tuple() if arg is None else (arg,)
448
+ methods = methods.copy()
449
+
450
+ if "cache" in methods:
451
+ # If "cache" is specified before the value has been evaluated, it
452
+ # raises an error. After the value is evaluated, it will succeed.
453
+ with pytest.raises(NotImplementedError):
454
+ getattr(dist, fname)(*args, method="cache")
455
+
456
+ ref = getattr(dist, fname)(*args)
457
+ check_nans_and_edges(dist, fname, arg, ref)
458
+
459
+ # Remove this after fixing `draw`
460
+ tol_override = {'atol': 1e-15}
461
+ # Mean can be 0, which makes logmean -inf.
462
+ if fname in {'logmean', 'mean', 'logskewness', 'skewness'}:
463
+ tol_override = {'atol': 1e-15}
464
+ elif fname in {'mode'}:
465
+ # can only expect about half of machine precision for optimization
466
+ # because math
467
+ tol_override = {'atol': 1e-6}
468
+ elif fname in {'logcdf'}: # gh-22276
469
+ tol_override = {'rtol': 2e-7}
470
+
471
+ if dist._overrides(f'_{fname}_formula'):
472
+ methods.add('formula')
473
+
474
+ np.testing.assert_equal(ref.shape, result_shape)
475
+ # Until we convert to array API, let's do the familiar thing:
476
+ # 0d things are scalars, not arrays
477
+ if result_shape == tuple():
478
+ assert np.isscalar(ref)
479
+
480
+ for method in methods:
481
+ res = getattr(dist, fname)(*args, method=method)
482
+ if 'log' in fname:
483
+ np.testing.assert_allclose(np.exp(res), np.exp(ref),
484
+ **tol_override)
485
+ else:
486
+ np.testing.assert_allclose(res, ref, **tol_override)
487
+
488
+ # for now, make sure dtypes are consistent; later, we can check whether
489
+ # they are correct.
490
+ np.testing.assert_equal(res.dtype, ref.dtype)
491
+ np.testing.assert_equal(res.shape, result_shape)
492
+ if result_shape == tuple():
493
+ assert np.isscalar(res)
494
+
495
+ def check_cdf2(dist, log, x, y, result_shape, methods):
496
+ # Specialized test for 2-arg cdf since the interface is a bit different
497
+ # from the other methods. Here, we'll use 1-arg cdf as a reference, and
498
+ # since we have already checked 1-arg cdf in `check_nans_and_edges`, this
499
+ # checks the equivalent of both `check_dist_func` and
500
+ # `check_nans_and_edges`.
501
+ methods = methods.copy()
502
+
503
+ if log:
504
+ if dist._overrides('_logcdf2_formula'):
505
+ methods.add('formula')
506
+ if dist._overrides('_logcdf_formula') or dist._overrides('_logccdf_formula'):
507
+ methods.add('subtraction')
508
+ if (dist._overrides('_cdf_formula')
509
+ or dist._overrides('_ccdf_formula')):
510
+ methods.add('log/exp')
511
+ else:
512
+ if dist._overrides('_cdf2_formula'):
513
+ methods.add('formula')
514
+ if dist._overrides('_cdf_formula') or dist._overrides('_ccdf_formula'):
515
+ methods.add('subtraction')
516
+ if (dist._overrides('_logcdf_formula')
517
+ or dist._overrides('_logccdf_formula')):
518
+ methods.add('log/exp')
519
+
520
+ ref = dist.cdf(y) - dist.cdf(x)
521
+ np.testing.assert_equal(ref.shape, result_shape)
522
+
523
+ if result_shape == tuple():
524
+ assert np.isscalar(ref)
525
+
526
+ for method in methods:
527
+ if isinstance(dist, DiscreteDistribution):
528
+ message = ("Two argument cdf functions are currently only supported for "
529
+ "continuous distributions.")
530
+ with pytest.raises(NotImplementedError, match=message):
531
+ res = (np.exp(dist.logcdf(x, y, method=method)) if log
532
+ else dist.cdf(x, y, method=method))
533
+ continue
534
+ res = (np.exp(dist.logcdf(x, y, method=method)) if log
535
+ else dist.cdf(x, y, method=method))
536
+ np.testing.assert_allclose(res, ref, atol=1e-14)
537
+ if log:
538
+ np.testing.assert_equal(res.dtype, (ref + 0j).dtype)
539
+ else:
540
+ np.testing.assert_equal(res.dtype, ref.dtype)
541
+ np.testing.assert_equal(res.shape, result_shape)
542
+ if result_shape == tuple():
543
+ assert np.isscalar(res)
544
+
545
+
546
+ def check_ccdf2(dist, log, x, y, result_shape, methods):
547
+ # Specialized test for 2-arg ccdf since the interface is a bit different
548
+ # from the other methods. Could be combined with check_cdf2 above, but
549
+ # writing it separately is simpler.
550
+ methods = methods.copy()
551
+
552
+ if dist._overrides(f'_{"log" if log else ""}ccdf2_formula'):
553
+ methods.add('formula')
554
+
555
+ ref = dist.cdf(x) + dist.ccdf(y)
556
+ np.testing.assert_equal(ref.shape, result_shape)
557
+
558
+ if result_shape == tuple():
559
+ assert np.isscalar(ref)
560
+
561
+ for method in methods:
562
+ message = ("Two argument cdf functions are currently only supported for "
563
+ "continuous distributions.")
564
+ if isinstance(dist, DiscreteDistribution):
565
+ with pytest.raises(NotImplementedError, match=message):
566
+ res = (np.exp(dist.logccdf(x, y, method=method)) if log
567
+ else dist.ccdf(x, y, method=method))
568
+ continue
569
+ res = (np.exp(dist.logccdf(x, y, method=method)) if log
570
+ else dist.ccdf(x, y, method=method))
571
+ np.testing.assert_allclose(res, ref, atol=1e-14)
572
+ np.testing.assert_equal(res.dtype, ref.dtype)
573
+ np.testing.assert_equal(res.shape, result_shape)
574
+ if result_shape == tuple():
575
+ assert np.isscalar(res)
576
+
577
+
578
+ def check_nans_and_edges(dist, fname, arg, res):
579
+
580
+ valid_parameters = get_valid_parameters(dist)
581
+ if fname in {'icdf', 'iccdf'}:
582
+ arg_domain = _RealInterval(endpoints=(0, 1), inclusive=(True, True))
583
+ elif fname in {'ilogcdf', 'ilogccdf'}:
584
+ arg_domain = _RealInterval(endpoints=(-inf, 0), inclusive=(True, True))
585
+ else:
586
+ arg_domain = dist._variable.domain
587
+
588
+ classified_args = classify_arg(dist, arg, arg_domain)
589
+ valid_parameters, *classified_args = np.broadcast_arrays(valid_parameters,
590
+ *classified_args)
591
+ valid_arg, endpoint_arg, outside_arg, nan_arg = classified_args
592
+ all_valid = valid_arg & valid_parameters
593
+
594
+ # Check NaN pattern and edge cases
595
+ assert_equal(res[~valid_parameters], np.nan)
596
+ assert_equal(res[nan_arg], np.nan)
597
+
598
+ a, b = dist.support()
599
+ a = np.broadcast_to(a, res.shape)
600
+ b = np.broadcast_to(b, res.shape)
601
+
602
+ outside_arg_minus = (outside_arg == -1) & valid_parameters
603
+ outside_arg_plus = (outside_arg == 1) & valid_parameters
604
+ endpoint_arg_minus = (endpoint_arg == -1) & valid_parameters
605
+ endpoint_arg_plus = (endpoint_arg == 1) & valid_parameters
606
+
607
+ is_discrete = isinstance(dist, DiscreteDistribution)
608
+ # Writing this independently of how the are set in the distribution
609
+ # infrastructure. That is very compact; this is very verbose.
610
+ if fname in {'logpdf'}:
611
+ assert_equal(res[outside_arg_minus], -np.inf)
612
+ assert_equal(res[outside_arg_plus], -np.inf)
613
+ ref = -np.inf if not is_discrete else np.inf
614
+ assert_equal(res[endpoint_arg_minus & ~valid_arg], ref)
615
+ assert_equal(res[endpoint_arg_plus & ~valid_arg], ref)
616
+ elif fname in {'pdf'}:
617
+ assert_equal(res[outside_arg_minus], 0)
618
+ assert_equal(res[outside_arg_plus], 0)
619
+ ref = 0 if not is_discrete else np.inf
620
+ assert_equal(res[endpoint_arg_minus & ~valid_arg], ref)
621
+ assert_equal(res[endpoint_arg_plus & ~valid_arg], ref)
622
+ elif fname in {'logcdf'} and not is_discrete:
623
+ assert_equal(res[outside_arg_minus], -inf)
624
+ assert_equal(res[outside_arg_plus], 0)
625
+ assert_equal(res[endpoint_arg_minus], -inf)
626
+ assert_equal(res[endpoint_arg_plus], 0)
627
+ elif fname in {'cdf'} and not is_discrete:
628
+ assert_equal(res[outside_arg_minus], 0)
629
+ assert_equal(res[outside_arg_plus], 1)
630
+ assert_equal(res[endpoint_arg_minus], 0)
631
+ assert_equal(res[endpoint_arg_plus], 1)
632
+ elif fname in {'logccdf'} and not is_discrete:
633
+ assert_equal(res[outside_arg_minus], 0)
634
+ assert_equal(res[outside_arg_plus], -inf)
635
+ assert_equal(res[endpoint_arg_minus], 0)
636
+ assert_equal(res[endpoint_arg_plus], -inf)
637
+ elif fname in {'ccdf'} and not is_discrete:
638
+ assert_equal(res[outside_arg_minus], 1)
639
+ assert_equal(res[outside_arg_plus], 0)
640
+ assert_equal(res[endpoint_arg_minus], 1)
641
+ assert_equal(res[endpoint_arg_plus], 0)
642
+ elif fname in {'ilogcdf', 'icdf'} and not is_discrete:
643
+ assert_equal(res[outside_arg == -1], np.nan)
644
+ assert_equal(res[outside_arg == 1], np.nan)
645
+ assert_equal(res[endpoint_arg == -1], a[endpoint_arg == -1])
646
+ assert_equal(res[endpoint_arg == 1], b[endpoint_arg == 1])
647
+ elif fname in {'ilogccdf', 'iccdf'} and not is_discrete:
648
+ assert_equal(res[outside_arg == -1], np.nan)
649
+ assert_equal(res[outside_arg == 1], np.nan)
650
+ assert_equal(res[endpoint_arg == -1], b[endpoint_arg == -1])
651
+ assert_equal(res[endpoint_arg == 1], a[endpoint_arg == 1])
652
+
653
+ exclude = {'logmean', 'mean', 'logskewness', 'skewness', 'support'}
654
+ if isinstance(dist, DiscreteDistribution):
655
+ exclude.update({'pdf', 'logpdf'})
656
+
657
+ if (
658
+ fname not in exclude
659
+ and not (isinstance(dist, Binomial)
660
+ and np.any((dist.n == 0) | (dist.p == 0) | (dist.p == 1)))):
661
+ # This can fail in degenerate case where Binomial distribution is a point
662
+ # distribution. Further on, we could factor out an is_degenerate function
663
+ # for the tests, or think about storing info about degeneracy in the
664
+ # instances.
665
+ assert np.isfinite(res[all_valid & (endpoint_arg == 0)]).all()
666
+
667
+
668
+ def check_moment_funcs(dist, result_shape):
669
+ # Check that all computation methods of all distribution functions agree
670
+ # with one another, effectively testing the correctness of the generic
671
+ # computation methods and confirming the consistency of specific
672
+ # distributions with their pdf/logpdf.
673
+
674
+ atol = 1e-9 # make this tighter (e.g. 1e-13) after fixing `draw`
675
+
676
+ def check(order, kind, method=None, ref=None, success=True):
677
+ if success:
678
+ res = dist.moment(order, kind, method=method)
679
+ assert_allclose(res, ref, atol=atol*10**order)
680
+ assert res.shape == ref.shape
681
+ else:
682
+ with pytest.raises(NotImplementedError):
683
+ dist.moment(order, kind, method=method)
684
+
685
+ def has_formula(order, kind):
686
+ formula_name = f'_moment_{kind}_formula'
687
+ overrides = dist._overrides(formula_name)
688
+ if not overrides:
689
+ return False
690
+ formula = getattr(dist, formula_name)
691
+ orders = getattr(formula, 'orders', set(range(6)))
692
+ return order in orders
693
+
694
+ dist.reset_cache()
695
+
696
+ ### Check Raw Moments ###
697
+ for i in range(6):
698
+ check(i, 'raw', 'cache', success=False) # not cached yet
699
+ ref = dist.moment(i, 'raw', method='quadrature')
700
+ check_nans_and_edges(dist, 'moment', None, ref)
701
+ assert ref.shape == result_shape
702
+ check(i, 'raw','cache', ref, success=True) # cached now
703
+ check(i, 'raw', 'formula', ref, success=has_formula(i, 'raw'))
704
+ check(i, 'raw', 'general', ref, success=(i == 0))
705
+ if dist.__class__ == stats.Normal:
706
+ check(i, 'raw', 'quadrature_icdf', ref, success=True)
707
+
708
+
709
+ # Clearing caches to better check their behavior
710
+ dist.reset_cache()
711
+
712
+ # If we have central or standard moment formulas, or if there are
713
+ # values in their cache, we can use method='transform'
714
+ dist.moment(0, 'central') # build up the cache
715
+ dist.moment(1, 'central')
716
+ for i in range(2, 6):
717
+ ref = dist.moment(i, 'raw', method='quadrature')
718
+ check(i, 'raw', 'transform', ref,
719
+ success=has_formula(i, 'central') or has_formula(i, 'standardized'))
720
+ dist.moment(i, 'central') # build up the cache
721
+ check(i, 'raw', 'transform', ref)
722
+
723
+ dist.reset_cache()
724
+
725
+ ### Check Central Moments ###
726
+
727
+ for i in range(6):
728
+ check(i, 'central', 'cache', success=False)
729
+ ref = dist.moment(i, 'central', method='quadrature')
730
+ assert ref.shape == result_shape
731
+ check(i, 'central', 'cache', ref, success=True)
732
+ check(i, 'central', 'formula', ref, success=has_formula(i, 'central'))
733
+ check(i, 'central', 'general', ref, success=i <= 1)
734
+ if dist.__class__ == stats.Normal:
735
+ check(i, 'central', 'quadrature_icdf', ref, success=True)
736
+ if not (dist.__class__ == stats.Uniform and i == 5):
737
+ # Quadrature is not super accurate for 5th central moment when the
738
+ # support is really big. Skip this one failing test. We need to come
739
+ # up with a better system of skipping individual failures w/ hypothesis.
740
+ check(i, 'central', 'transform', ref,
741
+ success=has_formula(i, 'raw') or (i <= 1))
742
+ if not has_formula(i, 'raw'):
743
+ dist.moment(i, 'raw')
744
+ check(i, 'central', 'transform', ref)
745
+
746
+ variance = dist.variance()
747
+ dist.reset_cache()
748
+
749
+ # If we have standard moment formulas, or if there are
750
+ # values in their cache, we can use method='normalize'
751
+ dist.moment(0, 'standardized') # build up the cache
752
+ dist.moment(1, 'standardized')
753
+ dist.moment(2, 'standardized')
754
+ for i in range(3, 6):
755
+ ref = dist.moment(i, 'central', method='quadrature')
756
+ check(i, 'central', 'normalize', ref,
757
+ success=has_formula(i, 'standardized') and not np.any(variance == 0))
758
+ dist.moment(i, 'standardized') # build up the cache
759
+ check(i, 'central', 'normalize', ref, success=not np.any(variance == 0))
760
+
761
+ ### Check Standardized Moments ###
762
+
763
+ var = dist.moment(2, 'central', method='quadrature')
764
+ dist.reset_cache()
765
+
766
+ for i in range(6):
767
+ check(i, 'standardized', 'cache', success=False)
768
+ ref = dist.moment(i, 'central', method='quadrature') / var ** (i / 2)
769
+ assert ref.shape == result_shape
770
+ check(i, 'standardized', 'formula', ref,
771
+ success=has_formula(i, 'standardized'))
772
+ if not (
773
+ isinstance(dist, Binomial)
774
+ and np.any((dist.n == 0) | (dist.p == 0) | (dist.p == 1))
775
+ ):
776
+ # This test will fail for degenerate case where binomial distribution
777
+ # is a point distribution.
778
+ check(i, 'standardized', 'general', ref, success=i <= 2)
779
+ check(i, 'standardized', 'normalize', ref)
780
+
781
+ if isinstance(dist, ShiftedScaledDistribution):
782
+ # logmoment is not fully fleshed out; no need to test
783
+ # ShiftedScaledDistribution here
784
+ return
785
+
786
+ # logmoment is not very accuate, and it's not public, so skip for now
787
+ # ### Check Against _logmoment ###
788
+ # logmean = dist._logmoment(1, logcenter=-np.inf)
789
+ # for i in range(6):
790
+ # ref = np.exp(dist._logmoment(i, logcenter=-np.inf))
791
+ # assert_allclose(dist.moment(i, 'raw'), ref, atol=atol*10**i)
792
+ #
793
+ # ref = np.exp(dist._logmoment(i, logcenter=logmean))
794
+ # assert_allclose(dist.moment(i, 'central'), ref, atol=atol*10**i)
795
+ #
796
+ # ref = np.exp(dist._logmoment(i, logcenter=logmean, standardized=True))
797
+ # assert_allclose(dist.moment(i, 'standardized'), ref, atol=atol*10**i)
798
+
799
+
800
+ @pytest.mark.parametrize('family', (Normal,))
801
+ @pytest.mark.parametrize('x_shape', [tuple(), (2, 3)])
802
+ @pytest.mark.parametrize('dist_shape', [tuple(), (4, 1)])
803
+ @pytest.mark.parametrize('fname', ['sample'])
804
+ @pytest.mark.parametrize('rng_type', [np.random.Generator, qmc.Halton, qmc.Sobol])
805
+ def test_sample_against_cdf(family, dist_shape, x_shape, fname, rng_type):
806
+ rng = np.random.default_rng(842582438235635)
807
+ num_parameters = family._num_parameters()
808
+
809
+ if dist_shape and num_parameters == 0:
810
+ pytest.skip("Distribution can't have a shape without parameters.")
811
+
812
+ dist = family._draw(dist_shape, rng)
813
+
814
+ n = 1024
815
+ sample_size = (n,) + x_shape
816
+ sample_array_shape = sample_size + dist_shape
817
+
818
+ if fname == 'sample':
819
+ sample_method = dist.sample
820
+
821
+ if rng_type != np.random.Generator:
822
+ rng = rng_type(d=1, seed=rng)
823
+ x = sample_method(sample_size, rng=rng)
824
+ assert x.shape == sample_array_shape
825
+
826
+ # probably should give `axis` argument to ks_1samp, review that separately
827
+ statistic = _kolmogorov_smirnov(dist, x, axis=0)
828
+ pvalue = kolmogn(x.shape[0], statistic, cdf=False)
829
+ p_threshold = 0.01
830
+ num_pvalues = pvalue.size
831
+ num_small_pvalues = np.sum(pvalue < p_threshold)
832
+ assert num_small_pvalues < p_threshold * num_pvalues
833
+
834
+
835
+ def get_valid_parameters(dist):
836
+ # Given a distribution, return a logical array that is true where all
837
+ # distribution parameters are within their respective domains. The code
838
+ # here is probably quite similar to that used to form the `_invalid`
839
+ # attribute of the distribution, but this was written about a week later
840
+ # without referring to that code, so it is a somewhat independent check.
841
+
842
+ # Get all parameter values and `_Parameter` objects
843
+ parameter_values = dist._parameters
844
+ parameters = {}
845
+ for parameterization in dist._parameterizations:
846
+ parameters.update(parameterization.parameters)
847
+
848
+ all_valid = np.ones(dist._shape, dtype=bool)
849
+ for name, value in parameter_values.items():
850
+ if name not in parameters: # cached value not part of parameterization
851
+ continue
852
+ parameter = parameters[name]
853
+
854
+ # Check that the numerical endpoints and inclusivity attribute
855
+ # agree with the `contains` method about which parameter values are
856
+ # within the domain.
857
+ a, b = parameter.domain.get_numerical_endpoints(
858
+ parameter_values=parameter_values)
859
+ a_included, b_included = parameter.domain.inclusive
860
+ valid = (a <= value) if a_included else a < value
861
+ valid &= (value <= b) if b_included else value < b
862
+ assert_equal(valid, parameter.domain.contains(
863
+ value, parameter_values=parameter_values))
864
+
865
+ # Form `all_valid` mask that is True where *all* parameters are valid
866
+ all_valid &= valid
867
+
868
+ # Check that the `all_valid` mask formed here is the complement of the
869
+ # `dist._invalid` mask stored by the infrastructure
870
+ assert_equal(~all_valid, dist._invalid)
871
+
872
+ return all_valid
873
+
874
+ def classify_arg(dist, arg, arg_domain):
875
+ if arg is None:
876
+ valid_args = np.ones(dist._shape, dtype=bool)
877
+ endpoint_args = np.zeros(dist._shape, dtype=bool)
878
+ outside_args = np.zeros(dist._shape, dtype=bool)
879
+ nan_args = np.zeros(dist._shape, dtype=bool)
880
+ return valid_args, endpoint_args, outside_args, nan_args
881
+
882
+ a, b = arg_domain.get_numerical_endpoints(
883
+ parameter_values=dist._parameters)
884
+
885
+ a, b, arg = np.broadcast_arrays(a, b, arg)
886
+ a_included, b_included = arg_domain.inclusive
887
+
888
+ inside = (a <= arg) if a_included else a < arg
889
+ inside &= (arg <= b) if b_included else arg < b
890
+ # TODO: add `supported` method and check here
891
+ on = np.zeros(a.shape, dtype=int)
892
+ on[a == arg] = -1
893
+ on[b == arg] = 1
894
+ outside = np.zeros(a.shape, dtype=int)
895
+ outside[(arg < a) if a_included else arg <= a] = -1
896
+ outside[(b < arg) if b_included else b <= arg] = 1
897
+ nan = np.isnan(arg)
898
+
899
+ return inside, on, outside, nan
900
+
901
+
902
+ def test_input_validation():
903
+ class Test(ContinuousDistribution):
904
+ _variable = _RealParameter('x', domain=_RealInterval())
905
+
906
+ message = ("The `Test` distribution family does not accept parameters, "
907
+ "but parameters `{'a'}` were provided.")
908
+ with pytest.raises(ValueError, match=message):
909
+ Test(a=1, )
910
+
911
+ message = "Attribute `tol` of `Test` must be a positive float, if specified."
912
+ with pytest.raises(ValueError, match=message):
913
+ Test(tol=np.asarray([]))
914
+ with pytest.raises(ValueError, match=message):
915
+ Test(tol=[1, 2, 3])
916
+ with pytest.raises(ValueError, match=message):
917
+ Test(tol=np.nan)
918
+ with pytest.raises(ValueError, match=message):
919
+ Test(tol=-1)
920
+
921
+ message = ("Argument `order` of `Test.moment` must be a "
922
+ "finite, positive integer.")
923
+ with pytest.raises(ValueError, match=message):
924
+ Test().moment(-1)
925
+ with pytest.raises(ValueError, match=message):
926
+ Test().moment(np.inf)
927
+
928
+ message = "Argument `kind` of `Test.moment` must be one of..."
929
+ with pytest.raises(ValueError, match=message):
930
+ Test().moment(2, kind='coconut')
931
+
932
+ class Test2(ContinuousDistribution):
933
+ _p1 = _RealParameter('c', domain=_RealInterval())
934
+ _p2 = _RealParameter('d', domain=_RealInterval())
935
+ _parameterizations = [_Parameterization(_p1, _p2)]
936
+ _variable = _RealParameter('x', domain=_RealInterval())
937
+
938
+ message = ("The provided parameters `{a}` do not match a supported "
939
+ "parameterization of the `Test2` distribution family.")
940
+ with pytest.raises(ValueError, match=message):
941
+ Test2(a=1)
942
+
943
+ message = ("The `Test2` distribution family requires parameters, but none "
944
+ "were provided.")
945
+ with pytest.raises(ValueError, match=message):
946
+ Test2()
947
+
948
+ message = ("The parameters `{c, d}` provided to the `Test2` "
949
+ "distribution family cannot be broadcast to the same shape.")
950
+ with pytest.raises(ValueError, match=message):
951
+ Test2(c=[1, 2], d=[1, 2, 3])
952
+
953
+ message = ("The argument provided to `Test2.pdf` cannot be be broadcast to "
954
+ "the same shape as the distribution parameters.")
955
+ with pytest.raises(ValueError, match=message):
956
+ dist = Test2(c=[1, 2, 3], d=[1, 2, 3])
957
+ dist.pdf([1, 2])
958
+
959
+ message = "Parameter `c` must be of real dtype."
960
+ with pytest.raises(TypeError, match=message):
961
+ Test2(c=[1, object()], d=[1, 2])
962
+
963
+ message = "Parameter `convention` of `Test2.kurtosis` must be one of..."
964
+ with pytest.raises(ValueError, match=message):
965
+ dist = Test2(c=[1, 2, 3], d=[1, 2, 3])
966
+ dist.kurtosis(convention='coconut')
967
+
968
+
969
+ def test_rng_deepcopy_pickle():
970
+ # test behavior of `rng` attribute and copy behavior
971
+ kwargs = dict(a=[-1, 2], b=10)
972
+ dist1 = Uniform(**kwargs)
973
+ dist2 = deepcopy(dist1)
974
+ dist3 = pickle.loads(pickle.dumps(dist1))
975
+
976
+ res1, res2, res3 = dist1.sample(), dist2.sample(), dist3.sample()
977
+ assert np.all(res2 != res1)
978
+ assert np.all(res3 != res1)
979
+
980
+ res1, res2, res3 = dist1.sample(rng=42), dist2.sample(rng=42), dist3.sample(rng=42)
981
+ assert np.all(res2 == res1)
982
+ assert np.all(res3 == res1)
983
+
984
+
985
+ class TestAttributes:
986
+ def test_cache_policy(self):
987
+ dist = StandardNormal(cache_policy="no_cache")
988
+ # make error message more appropriate
989
+ message = "`StandardNormal` does not provide an accurate implementation of the "
990
+ with pytest.raises(NotImplementedError, match=message):
991
+ dist.mean(method='cache')
992
+ mean = dist.mean()
993
+ with pytest.raises(NotImplementedError, match=message):
994
+ dist.mean(method='cache')
995
+
996
+ # add to enum
997
+ dist.cache_policy = None
998
+ with pytest.raises(NotImplementedError, match=message):
999
+ dist.mean(method='cache')
1000
+ mean = dist.mean() # method is 'formula' by default
1001
+ cached_mean = dist.mean(method='cache')
1002
+ assert_equal(cached_mean, mean)
1003
+
1004
+ # cache is overridden by latest evaluation
1005
+ quadrature_mean = dist.mean(method='quadrature')
1006
+ cached_mean = dist.mean(method='cache')
1007
+ assert_equal(cached_mean, quadrature_mean)
1008
+ assert not np.all(mean == quadrature_mean)
1009
+
1010
+ # We can turn the cache off, and it won't change, but the old cache is
1011
+ # still available
1012
+ dist.cache_policy = "no_cache"
1013
+ mean = dist.mean(method='formula')
1014
+ cached_mean = dist.mean(method='cache')
1015
+ assert_equal(cached_mean, quadrature_mean)
1016
+ assert not np.all(mean == quadrature_mean)
1017
+
1018
+ dist.reset_cache()
1019
+ with pytest.raises(NotImplementedError, match=message):
1020
+ dist.mean(method='cache')
1021
+
1022
+ message = "Attribute `cache_policy` of `StandardNormal`..."
1023
+ with pytest.raises(ValueError, match=message):
1024
+ dist.cache_policy = "invalid"
1025
+
1026
+ def test_tol(self):
1027
+ x = 3.
1028
+ X = stats.Normal()
1029
+
1030
+ message = "Attribute `tol` of `StandardNormal` must..."
1031
+ with pytest.raises(ValueError, match=message):
1032
+ X.tol = -1.
1033
+ with pytest.raises(ValueError, match=message):
1034
+ X.tol = (0.1,)
1035
+ with pytest.raises(ValueError, match=message):
1036
+ X.tol = np.nan
1037
+
1038
+ X1 = stats.Normal(tol=1e-1)
1039
+ X2 = stats.Normal(tol=1e-12)
1040
+ ref = X.cdf(x)
1041
+ res1 = X1.cdf(x, method='quadrature')
1042
+ res2 = X2.cdf(x, method='quadrature')
1043
+ assert_allclose(res1, ref, rtol=X1.tol)
1044
+ assert_allclose(res2, ref, rtol=X2.tol)
1045
+ assert abs(res1 - ref) > abs(res2 - ref)
1046
+
1047
+ p = 0.99
1048
+ X1.tol, X2.tol = X2.tol, X1.tol
1049
+ ref = X.icdf(p)
1050
+ res1 = X1.icdf(p, method='inversion')
1051
+ res2 = X2.icdf(p, method='inversion')
1052
+ assert_allclose(res1, ref, rtol=X1.tol)
1053
+ assert_allclose(res2, ref, rtol=X2.tol)
1054
+ assert abs(res2 - ref) > abs(res1 - ref)
1055
+
1056
+ def test_iv_policy(self):
1057
+ X = Uniform(a=0, b=1)
1058
+ assert X.pdf(2) == 0
1059
+
1060
+ X.validation_policy = 'skip_all'
1061
+ assert X.pdf(np.asarray(2.)) == 1
1062
+
1063
+ # Tests _set_invalid_nan
1064
+ a, b = np.asarray(1.), np.asarray(0.) # invalid parameters
1065
+ X = Uniform(a=a, b=b, validation_policy='skip_all')
1066
+ assert X.pdf(np.asarray(2.)) == -1
1067
+
1068
+ # Tests _set_invalid_nan_property
1069
+ class MyUniform(Uniform):
1070
+ def _entropy_formula(self, *args, **kwargs):
1071
+ return 'incorrect'
1072
+
1073
+ def _moment_raw_formula(self, order, **params):
1074
+ return 'incorrect'
1075
+
1076
+ X = MyUniform(a=a, b=b, validation_policy='skip_all')
1077
+ assert X.entropy() == 'incorrect'
1078
+
1079
+ # Tests _validate_order_kind
1080
+ assert X.moment(kind='raw', order=-1) == 'incorrect'
1081
+
1082
+ # Test input validation
1083
+ message = "Attribute `validation_policy` of `MyUniform`..."
1084
+ with pytest.raises(ValueError, match=message):
1085
+ X.validation_policy = "invalid"
1086
+
1087
+ def test_shapes(self):
1088
+ X = stats.Normal(mu=1, sigma=2)
1089
+ Y = stats.Normal(mu=[2], sigma=3)
1090
+
1091
+ # Check that attributes are available as expected
1092
+ assert X.mu == 1
1093
+ assert X.sigma == 2
1094
+ assert Y.mu[0] == 2
1095
+ assert Y.sigma[0] == 3
1096
+
1097
+ # Trying to set an attribute raises
1098
+ # message depends on Python version
1099
+ with pytest.raises(AttributeError):
1100
+ X.mu = 2
1101
+
1102
+ # Trying to mutate an attribute really mutates a copy
1103
+ Y.mu[0] = 10
1104
+ assert Y.mu[0] == 2
1105
+
1106
+
1107
+ class TestMakeDistribution:
1108
+ @pytest.mark.parametrize('i, distdata', enumerate(distcont + distdiscrete))
1109
+ def test_rv_generic(self, i, distdata):
1110
+ distname = distdata[0]
1111
+
1112
+ slow = {'argus', 'exponpow', 'exponweib', 'genexpon', 'gompertz', 'halfgennorm',
1113
+ 'johnsonsb', 'kappa4', 'ksone', 'kstwo', 'kstwobign', 'norminvgauss',
1114
+ 'powerlognorm', 'powernorm', 'recipinvgauss', 'studentized_range',
1115
+ 'vonmises_line', # continuous
1116
+ 'betanbinom', 'logser', 'skellam', 'zipf'} # discrete
1117
+ if not int(os.environ.get('SCIPY_XSLOW', '0')) and distname in slow:
1118
+ pytest.skip('Skipping as XSLOW')
1119
+
1120
+ if distname in { # skip these distributions
1121
+ 'levy_stable', # private methods seem to require >= 1d args
1122
+ 'vonmises', # circular distribution; shouldn't work
1123
+ 'poisson_binom', # vector shape parameter
1124
+ 'hypergeom', # distribution functions need interpolation
1125
+ 'nchypergeom_fisher', # distribution functions need interpolation
1126
+ 'nchypergeom_wallenius', # distribution functions need interpolation
1127
+ }:
1128
+ return
1129
+
1130
+ # skip single test, mostly due to slight disagreement
1131
+ custom_tolerances = {'ksone': 1e-5, 'kstwo': 1e-5} # discontinuous PDF
1132
+ skip_entropy = {'kstwobign', 'pearson3'} # tolerance issue
1133
+ skip_skewness = {'exponpow', 'ksone', 'nchypergeom_wallenius'} # tolerance
1134
+ skip_kurtosis = {'chi', 'exponpow', 'invgamma', # tolerance
1135
+ 'johnsonsb', 'ksone', 'kstwo', # tolerance
1136
+ 'nchypergeom_wallenius'} # tolerance
1137
+ skip_logccdf = {'arcsine', 'skewcauchy', 'trapezoid', 'triang'} # tolerance
1138
+ skip_raw = {2: {'alpha', 'foldcauchy', 'halfcauchy', 'levy', 'levy_l'},
1139
+ 3: {'pareto'}, # stats.pareto is just wrong
1140
+ 4: {'invgamma'}} # tolerance issue
1141
+ skip_standardized = {'exponpow', 'ksone'} # tolerances
1142
+
1143
+ dist = getattr(stats, distname)
1144
+ params = dict(zip(dist.shapes.split(', '), distdata[1])) if dist.shapes else {}
1145
+ rng = np.random.default_rng(7548723590230982)
1146
+ CustomDistribution = stats.make_distribution(dist)
1147
+ X = CustomDistribution(**params)
1148
+ Y = dist(**params)
1149
+ x = X.sample(shape=10, rng=rng)
1150
+ p = X.cdf(x)
1151
+ rtol = custom_tolerances.get(distname, 1e-7)
1152
+ atol = 1e-12
1153
+
1154
+ with np.errstate(divide='ignore', invalid='ignore'):
1155
+ m, v, s, k = Y.stats('mvsk')
1156
+ assert_allclose(X.support(), Y.support())
1157
+ if distname not in skip_entropy:
1158
+ assert_allclose(X.entropy(), Y.entropy(), rtol=rtol)
1159
+ if isinstance(Y, stats.rv_discrete):
1160
+ # some continuous distributions have trouble with `logentropy` because
1161
+ # it uses complex numbers
1162
+ assert_allclose(np.exp(X.logentropy()), Y.entropy(), rtol=rtol)
1163
+ assert_allclose(X.median(), Y.median(), rtol=rtol)
1164
+ assert_allclose(X.mean(), m, rtol=rtol, atol=atol)
1165
+ assert_allclose(X.variance(), v, rtol=rtol, atol=atol)
1166
+ if distname not in skip_skewness:
1167
+ assert_allclose(X.skewness(), s, rtol=rtol, atol=atol)
1168
+ if distname not in skip_kurtosis:
1169
+ assert_allclose(X.kurtosis(convention='excess'), k,
1170
+ rtol=rtol, atol=atol)
1171
+ if isinstance(dist, stats.rv_continuous):
1172
+ assert_allclose(X.logpdf(x), Y.logpdf(x), rtol=rtol)
1173
+ assert_allclose(X.pdf(x), Y.pdf(x), rtol=rtol)
1174
+ else:
1175
+ assert_allclose(X.logpmf(x), Y.logpmf(x), rtol=rtol)
1176
+ assert_allclose(X.pmf(x), Y.pmf(x), rtol=rtol)
1177
+ assert_allclose(X.logcdf(x), Y.logcdf(x), rtol=rtol)
1178
+ assert_allclose(X.cdf(x), Y.cdf(x), rtol=rtol)
1179
+ if distname not in skip_logccdf:
1180
+ assert_allclose(X.logccdf(x), Y.logsf(x), rtol=rtol)
1181
+ assert_allclose(X.ccdf(x), Y.sf(x), rtol=rtol)
1182
+
1183
+ # old infrastructure convention for ppf(p=0) and isf(p=1) is different than
1184
+ # new infrastructure. Adjust reference values accordingly.
1185
+ a, _ = Y.support()
1186
+ ref_ppf = Y.ppf(p)
1187
+ ref_ppf[p == 0] = a
1188
+ ref_isf = Y.isf(p)
1189
+ ref_isf[p == 1] = a
1190
+
1191
+ assert_allclose(X.icdf(p), ref_ppf, rtol=rtol)
1192
+ assert_allclose(X.iccdf(p), ref_isf, rtol=rtol)
1193
+
1194
+ for order in range(5):
1195
+ if distname not in skip_raw.get(order, {}):
1196
+ assert_allclose(X.moment(order, kind='raw'),
1197
+ Y.moment(order), rtol=rtol, atol=atol)
1198
+ for order in range(3, 4):
1199
+ if distname not in skip_standardized:
1200
+ assert_allclose(X.moment(order, kind='standardized'),
1201
+ Y.stats('mvsk'[order-1]), rtol=rtol, atol=atol)
1202
+ if isinstance(dist, stats.rv_continuous):
1203
+ # For discrete distributions, these won't agree at the far left end
1204
+ # of the support, and the new infrastructure is slow there (for now).
1205
+ seed = 845298245687345
1206
+ assert_allclose(X.sample(shape=10, rng=seed),
1207
+ Y.rvs(size=10,
1208
+ random_state=np.random.default_rng(seed)),
1209
+ rtol=rtol)
1210
+
1211
+ def test_custom(self):
1212
+ rng = np.random.default_rng(7548723590230982)
1213
+
1214
+ class MyLogUniform:
1215
+ @property
1216
+ def __make_distribution_version__(self):
1217
+ return "1.16.0"
1218
+
1219
+ @property
1220
+ def parameters(self):
1221
+ return {'a': {'endpoints': (0, np.inf), 'inclusive': (False, False)},
1222
+ 'b': {'endpoints': ('a', np.inf), 'inclusive': (False, False)}}
1223
+
1224
+ @property
1225
+ def support(self):
1226
+ return {'endpoints': ('a', 'b')}
1227
+
1228
+ def pdf(self, x, a, b):
1229
+ return 1 / (x * (np.log(b) - np.log(a)))
1230
+
1231
+ def sample(self, shape, *, a, b, rng=None):
1232
+ p = rng.uniform(size=shape)
1233
+ return np.exp(np.log(a) + p * (np.log(b) - np.log(a)))
1234
+
1235
+ def moment(self, order, kind='raw', *, a, b):
1236
+ if order == 1 and kind == 'raw':
1237
+ # quadrature is perfectly accurate here; add 1e-10 error so we
1238
+ # can tell the difference between the two
1239
+ return (b - a) / np.log(b/a) + 1e-10
1240
+
1241
+ LogUniform = stats.make_distribution(MyLogUniform())
1242
+
1243
+ X = LogUniform(a=np.exp(1), b=np.exp(3))
1244
+ Y = stats.exp(Uniform(a=1., b=3.))
1245
+ x = X.sample(shape=10, rng=rng)
1246
+ p = X.cdf(x)
1247
+
1248
+ assert_allclose(X.support(), Y.support())
1249
+ assert_allclose(X.entropy(), Y.entropy())
1250
+ assert_allclose(X.median(), Y.median())
1251
+ assert_allclose(X.logpdf(x), Y.logpdf(x))
1252
+ assert_allclose(X.pdf(x), Y.pdf(x))
1253
+ assert_allclose(X.logcdf(x), Y.logcdf(x))
1254
+ assert_allclose(X.cdf(x), Y.cdf(x))
1255
+ assert_allclose(X.logccdf(x), Y.logccdf(x))
1256
+ assert_allclose(X.ccdf(x), Y.ccdf(x))
1257
+ assert_allclose(X.icdf(p), Y.icdf(p))
1258
+ assert_allclose(X.iccdf(p), Y.iccdf(p))
1259
+ for kind in ['raw', 'central', 'standardized']:
1260
+ for order in range(5):
1261
+ assert_allclose(X.moment(order, kind=kind),
1262
+ Y.moment(order, kind=kind))
1263
+
1264
+ # Confirm that the `sample` and `moment` methods are overriden as expected
1265
+ sample_formula = X.sample(shape=10, rng=0, method='formula')
1266
+ sample_inverse = X.sample(shape=10, rng=0, method='inverse_transform')
1267
+ assert_allclose(sample_formula, sample_inverse)
1268
+ assert not np.all(sample_formula == sample_inverse)
1269
+
1270
+ assert_allclose(X.mean(method='formula'), X.mean(method='quadrature'))
1271
+ assert not X.mean(method='formula') == X.mean(method='quadrature')
1272
+
1273
+ # pdf and cdf formulas below can warn on boundary of support in some cases.
1274
+ # See https://github.com/scipy/scipy/pull/22560#discussion_r1962763840.
1275
+ @pytest.mark.slow
1276
+ @pytest.mark.filterwarnings("ignore::RuntimeWarning")
1277
+ @pytest.mark.parametrize("c", [-1, 0, 1, np.asarray([-2.1, -1., 0., 1., 2.1])])
1278
+ def test_custom_variable_support(self, c):
1279
+ rng = np.random.default_rng(7548723590230982)
1280
+
1281
+ class MyGenExtreme:
1282
+ @property
1283
+ def __make_distribution_version__(self):
1284
+ return "1.16.0"
1285
+
1286
+ @property
1287
+ def parameters(self):
1288
+ return {
1289
+ 'c': {'endpoints': (-np.inf, np.inf), 'inclusive': (False, False)},
1290
+ 'mu': {'endpoints': (-np.inf, np.inf), 'inclusive': (False, False)},
1291
+ 'sigma': {'endpoints': (0, np.inf), 'inclusive': (False, False)}
1292
+ }
1293
+
1294
+ @property
1295
+ def support(self):
1296
+ def left(*, c, mu, sigma):
1297
+ c, mu, sigma = np.broadcast_arrays(c, mu, sigma)
1298
+ result = np.empty_like(c)
1299
+ result[c >= 0] = -np.inf
1300
+ result[c < 0] = mu[c < 0] + sigma[c < 0] / c[c < 0]
1301
+ return result[()]
1302
+
1303
+ def right(*, c, mu, sigma):
1304
+ c, mu, sigma = np.broadcast_arrays(c, mu, sigma)
1305
+ result = np.empty_like(c)
1306
+ result[c <= 0] = np.inf
1307
+ result[c > 0] = mu[c > 0] + sigma[c > 0] / c[c > 0]
1308
+ return result[()]
1309
+
1310
+ return {"endpoints": (left, right), "inclusive": (False, False)}
1311
+
1312
+ def pdf(self, x, *, c, mu, sigma):
1313
+ x, c, mu, sigma = np.broadcast_arrays(x, c, mu, sigma)
1314
+ t = np.empty_like(x)
1315
+ mask = (c == 0)
1316
+ t[mask] = np.exp(-(x[mask] - mu[mask])/sigma[mask])
1317
+ t[~mask] = (
1318
+ 1 - c[~mask]*(x[~mask] - mu[~mask])/sigma[~mask]
1319
+ )**(1/c[~mask])
1320
+ result = 1/sigma * t**(1 - c)*np.exp(-t)
1321
+ return result[()]
1322
+
1323
+ def cdf(self, x, *, c, mu, sigma):
1324
+ x, c, mu, sigma = np.broadcast_arrays(x, c, mu, sigma)
1325
+ t = np.empty_like(x)
1326
+ mask = (c == 0)
1327
+ t[mask] = np.exp(-(x[mask] - mu[mask])/sigma[mask])
1328
+ t[~mask] = (
1329
+ 1 - c[~mask]*(x[~mask] - mu[~mask])/sigma[~mask]
1330
+ )**(1/c[~mask])
1331
+ return np.exp(-t)[()]
1332
+
1333
+ GenExtreme1 = stats.make_distribution(MyGenExtreme())
1334
+ GenExtreme2 = stats.make_distribution(stats.genextreme)
1335
+
1336
+ X1 = GenExtreme1(c=c, mu=0, sigma=1)
1337
+ X2 = GenExtreme2(c=c)
1338
+
1339
+ x = X1.sample(shape=10, rng=rng)
1340
+ p = X1.cdf(x)
1341
+
1342
+ assert_allclose(X1.support(), X2.support())
1343
+ assert_allclose(X1.entropy(), X2.entropy(), rtol=5e-6)
1344
+ assert_allclose(X1.median(), X2.median())
1345
+ assert_allclose(X1.logpdf(x), X2.logpdf(x))
1346
+ assert_allclose(X1.pdf(x), X2.pdf(x))
1347
+ assert_allclose(X1.logcdf(x), X2.logcdf(x))
1348
+ assert_allclose(X1.cdf(x), X2.cdf(x))
1349
+ assert_allclose(X1.logccdf(x), X2.logccdf(x))
1350
+ assert_allclose(X1.ccdf(x), X2.ccdf(x))
1351
+ assert_allclose(X1.icdf(p), X2.icdf(p))
1352
+ assert_allclose(X1.iccdf(p), X2.iccdf(p))
1353
+
1354
+ @pytest.mark.slow
1355
+ @pytest.mark.parametrize("a", [0.5, np.asarray([0.5, 1.0, 2.0, 4.0, 8.0])])
1356
+ @pytest.mark.parametrize("b", [0.5, np.asarray([0.5, 1.0, 2.0, 4.0, 8.0])])
1357
+ def test_custom_multiple_parameterizations(self, a, b):
1358
+ rng = np.random.default_rng(7548723590230982)
1359
+ class MyBeta:
1360
+ @property
1361
+ def __make_distribution_version__(self):
1362
+ return "1.16.0"
1363
+
1364
+ @property
1365
+ def parameters(self):
1366
+ return (
1367
+ {"a": (0, np.inf), "b": (0, np.inf)},
1368
+ {"mu": (0, 1), "nu": (0, np.inf)},
1369
+ )
1370
+
1371
+ def process_parameters(self, a=None, b=None, mu=None, nu=None):
1372
+ if a is not None and b is not None and mu is None and nu is None:
1373
+ nu = a + b
1374
+ mu = a / nu
1375
+ else:
1376
+ a = mu * nu
1377
+ b = nu - a
1378
+ return {"a": a, "b": b, "mu": mu, "nu": nu}
1379
+
1380
+ @property
1381
+ def support(self):
1382
+ return {'endpoints': (0, 1)}
1383
+
1384
+ def pdf(self, x, a, b, mu, nu):
1385
+ return special._ufuncs._beta_pdf(x, a, b)
1386
+
1387
+ def cdf(self, x, a, b, mu, nu):
1388
+ return special.betainc(a, b, x)
1389
+
1390
+ Beta = stats.make_distribution(stats.beta)
1391
+ MyBeta = stats.make_distribution(MyBeta())
1392
+
1393
+ mu = a / (a + b)
1394
+ nu = a + b
1395
+
1396
+ X = MyBeta(a=a, b=b)
1397
+ Y = MyBeta(mu=mu, nu=nu)
1398
+ Z = Beta(a=a, b=b)
1399
+
1400
+ x = Z.sample(shape=10, rng=rng)
1401
+ p = Z.cdf(x)
1402
+
1403
+ assert_allclose(X.support(), Z.support())
1404
+ assert_allclose(X.median(), Z.median())
1405
+ assert_allclose(X.pdf(x), Z.pdf(x))
1406
+ assert_allclose(X.cdf(x), Z.cdf(x))
1407
+ assert_allclose(X.ccdf(x), Z.ccdf(x))
1408
+ assert_allclose(X.icdf(p), Z.icdf(p))
1409
+ assert_allclose(X.iccdf(p), Z.iccdf(p))
1410
+
1411
+ assert_allclose(Y.support(), Z.support())
1412
+ assert_allclose(Y.median(), Z.median())
1413
+ assert_allclose(Y.pdf(x), Z.pdf(x))
1414
+ assert_allclose(Y.cdf(x), Z.cdf(x))
1415
+ assert_allclose(Y.ccdf(x), Z.ccdf(x))
1416
+ assert_allclose(Y.icdf(p), Z.icdf(p))
1417
+ assert_allclose(Y.iccdf(p), Z.iccdf(p))
1418
+
1419
+ def test_input_validation(self):
1420
+ message = '`levy_stable` is not supported.'
1421
+ with pytest.raises(NotImplementedError, match=message):
1422
+ stats.make_distribution(stats.levy_stable)
1423
+
1424
+ message = '`vonmises` is not supported.'
1425
+ with pytest.raises(NotImplementedError, match=message):
1426
+ stats.make_distribution(stats.vonmises)
1427
+
1428
+ message = "The argument must be an instance of..."
1429
+ with pytest.raises(ValueError, match=message):
1430
+ stats.make_distribution(object())
1431
+
1432
+ def test_repr_str_docs(self):
1433
+ from scipy.stats._distribution_infrastructure import _distribution_names
1434
+ for dist in _distribution_names.keys():
1435
+ assert hasattr(stats, dist)
1436
+
1437
+ dist = stats.make_distribution(stats.gamma)
1438
+ assert str(dist(a=2)) == "Gamma(a=2.0)"
1439
+ if np.__version__ >= "2":
1440
+ assert repr(dist(a=2)) == "Gamma(a=np.float64(2.0))"
1441
+ assert 'Gamma' in dist.__doc__
1442
+
1443
+ dist = stats.make_distribution(stats.halfgennorm)
1444
+ assert str(dist(beta=2)) == "HalfGeneralizedNormal(beta=2.0)"
1445
+ if np.__version__ >= "2":
1446
+ assert repr(dist(beta=2)) == "HalfGeneralizedNormal(beta=np.float64(2.0))"
1447
+ assert 'HalfGeneralizedNormal' in dist.__doc__
1448
+
1449
+
1450
+ class TestTransforms:
1451
+
1452
+ def test_ContinuousDistribution_only(self):
1453
+ X = stats.Binomial(n=10, p=0.5)
1454
+ # This is applied at the top level TransformedDistribution,
1455
+ # so testing one subclass is enough
1456
+ message = "Transformations are currently only supported for continuous RVs."
1457
+ with pytest.raises(NotImplementedError, match=message):
1458
+ stats.exp(X)
1459
+
1460
+ def test_truncate(self):
1461
+ rng = np.random.default_rng(81345982345826)
1462
+ lb = rng.random((3, 1))
1463
+ ub = rng.random((3, 1))
1464
+ lb, ub = np.minimum(lb, ub), np.maximum(lb, ub)
1465
+
1466
+ Y = stats.truncate(Normal(), lb=lb, ub=ub)
1467
+ Y0 = stats.truncnorm(lb, ub)
1468
+
1469
+ y = Y0.rvs((3, 10), random_state=rng)
1470
+ p = Y0.cdf(y)
1471
+
1472
+ assert_allclose(Y.logentropy(), np.log(Y0.entropy() + 0j))
1473
+ assert_allclose(Y.entropy(), Y0.entropy())
1474
+ assert_allclose(Y.median(), Y0.ppf(0.5))
1475
+ assert_allclose(Y.mean(), Y0.mean())
1476
+ assert_allclose(Y.variance(), Y0.var())
1477
+ assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
1478
+ assert_allclose(Y.skewness(), Y0.stats('s'))
1479
+ assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
1480
+ assert_allclose(Y.support(), Y0.support())
1481
+ assert_allclose(Y.pdf(y), Y0.pdf(y))
1482
+ assert_allclose(Y.cdf(y), Y0.cdf(y))
1483
+ assert_allclose(Y.ccdf(y), Y0.sf(y))
1484
+ assert_allclose(Y.icdf(p), Y0.ppf(p))
1485
+ assert_allclose(Y.iccdf(p), Y0.isf(p))
1486
+ assert_allclose(Y.logpdf(y), Y0.logpdf(y))
1487
+ assert_allclose(Y.logcdf(y), Y0.logcdf(y))
1488
+ assert_allclose(Y.logccdf(y), Y0.logsf(y))
1489
+ assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
1490
+ assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
1491
+ sample = Y.sample(10)
1492
+ assert np.all((sample > lb) & (sample < ub))
1493
+
1494
+ @pytest.mark.fail_slow(10)
1495
+ @given(data=strategies.data(), seed=strategies.integers(min_value=0))
1496
+ @pytest.mark.thread_unsafe
1497
+ def test_loc_scale(self, data, seed):
1498
+ # Need tests with negative scale
1499
+ rng = np.random.default_rng(seed)
1500
+
1501
+ class TransformedNormal(ShiftedScaledDistribution):
1502
+ def __init__(self, *args, **kwargs):
1503
+ super().__init__(StandardNormal(), *args, **kwargs)
1504
+
1505
+ tmp = draw_distribution_from_family(
1506
+ TransformedNormal, data, rng, proportions=(1, 0, 0, 0), min_side=1)
1507
+ dist, x, y, p, logp, result_shape, x_result_shape, xy_result_shape = tmp
1508
+
1509
+ loc = dist.loc
1510
+ scale = dist.scale
1511
+ dist0 = StandardNormal()
1512
+ dist_ref = stats.norm(loc=loc, scale=scale)
1513
+
1514
+ x0 = (x - loc) / scale
1515
+ y0 = (y - loc) / scale
1516
+
1517
+ a, b = dist.support()
1518
+ a0, b0 = dist0.support()
1519
+ assert_allclose(a, a0 + loc)
1520
+ assert_allclose(b, b0 + loc)
1521
+
1522
+ with np.errstate(invalid='ignore', divide='ignore'):
1523
+ assert_allclose(np.exp(dist.logentropy()), dist.entropy())
1524
+ assert_allclose(dist.entropy(), dist_ref.entropy())
1525
+ assert_allclose(dist.median(), dist0.median() + loc)
1526
+ assert_allclose(dist.mode(), dist0.mode() + loc)
1527
+ assert_allclose(dist.mean(), dist0.mean() + loc)
1528
+ assert_allclose(dist.variance(), dist0.variance() * scale**2)
1529
+ assert_allclose(dist.standard_deviation(), dist.variance()**0.5)
1530
+ assert_allclose(dist.skewness(), dist0.skewness() * np.sign(scale))
1531
+ assert_allclose(dist.kurtosis(), dist0.kurtosis())
1532
+ assert_allclose(dist.logpdf(x), dist0.logpdf(x0) - np.log(scale))
1533
+ assert_allclose(dist.pdf(x), dist0.pdf(x0) / scale)
1534
+ assert_allclose(dist.logcdf(x), dist0.logcdf(x0))
1535
+ assert_allclose(dist.cdf(x), dist0.cdf(x0))
1536
+ assert_allclose(dist.logccdf(x), dist0.logccdf(x0))
1537
+ assert_allclose(dist.ccdf(x), dist0.ccdf(x0))
1538
+ assert_allclose(dist.logcdf(x, y), dist0.logcdf(x0, y0))
1539
+ assert_allclose(dist.cdf(x, y), dist0.cdf(x0, y0))
1540
+ assert_allclose(dist.logccdf(x, y), dist0.logccdf(x0, y0))
1541
+ assert_allclose(dist.ccdf(x, y), dist0.ccdf(x0, y0))
1542
+ assert_allclose(dist.ilogcdf(logp), dist0.ilogcdf(logp)*scale + loc)
1543
+ assert_allclose(dist.icdf(p), dist0.icdf(p)*scale + loc)
1544
+ assert_allclose(dist.ilogccdf(logp), dist0.ilogccdf(logp)*scale + loc)
1545
+ assert_allclose(dist.iccdf(p), dist0.iccdf(p)*scale + loc)
1546
+ for i in range(1, 5):
1547
+ assert_allclose(dist.moment(i, 'raw'), dist_ref.moment(i))
1548
+ assert_allclose(dist.moment(i, 'central'),
1549
+ dist0.moment(i, 'central') * scale**i)
1550
+ assert_allclose(dist.moment(i, 'standardized'),
1551
+ dist0.moment(i, 'standardized') * np.sign(scale)**i)
1552
+
1553
+ # Transform back to the original distribution using all arithmetic
1554
+ # operations; check that it behaves as expected.
1555
+ dist = (dist - 2*loc) + loc
1556
+ dist = dist/scale**2 * scale
1557
+ z = np.zeros(dist._shape) # compact broadcasting
1558
+
1559
+ a, b = dist.support()
1560
+ a0, b0 = dist0.support()
1561
+ assert_allclose(a, a0 + z)
1562
+ assert_allclose(b, b0 + z)
1563
+
1564
+ with np.errstate(invalid='ignore', divide='ignore'):
1565
+ assert_allclose(dist.logentropy(), dist0.logentropy() + z)
1566
+ assert_allclose(dist.entropy(), dist0.entropy() + z)
1567
+ assert_allclose(dist.median(), dist0.median() + z)
1568
+ assert_allclose(dist.mode(), dist0.mode() + z)
1569
+ assert_allclose(dist.mean(), dist0.mean() + z)
1570
+ assert_allclose(dist.variance(), dist0.variance() + z)
1571
+ assert_allclose(dist.standard_deviation(), dist0.standard_deviation() + z)
1572
+ assert_allclose(dist.skewness(), dist0.skewness() + z)
1573
+ assert_allclose(dist.kurtosis(), dist0.kurtosis() + z)
1574
+ assert_allclose(dist.logpdf(x), dist0.logpdf(x)+z)
1575
+ assert_allclose(dist.pdf(x), dist0.pdf(x) + z)
1576
+ assert_allclose(dist.logcdf(x), dist0.logcdf(x) + z)
1577
+ assert_allclose(dist.cdf(x), dist0.cdf(x) + z)
1578
+ assert_allclose(dist.logccdf(x), dist0.logccdf(x) + z)
1579
+ assert_allclose(dist.ccdf(x), dist0.ccdf(x) + z)
1580
+ assert_allclose(dist.ilogcdf(logp), dist0.ilogcdf(logp) + z)
1581
+ assert_allclose(dist.icdf(p), dist0.icdf(p) + z)
1582
+ assert_allclose(dist.ilogccdf(logp), dist0.ilogccdf(logp) + z)
1583
+ assert_allclose(dist.iccdf(p), dist0.iccdf(p) + z)
1584
+ for i in range(1, 5):
1585
+ assert_allclose(dist.moment(i, 'raw'), dist0.moment(i, 'raw'))
1586
+ assert_allclose(dist.moment(i, 'central'), dist0.moment(i, 'central'))
1587
+ assert_allclose(dist.moment(i, 'standardized'),
1588
+ dist0.moment(i, 'standardized'))
1589
+
1590
+ # These are tough to compare because of the way the shape works
1591
+ # rng = np.random.default_rng(seed)
1592
+ # rng0 = np.random.default_rng(seed)
1593
+ # assert_allclose(dist.sample(x_result_shape, rng=rng),
1594
+ # dist0.sample(x_result_shape, rng=rng0) * scale + loc)
1595
+ # Should also try to test fit, plot?
1596
+
1597
+ @pytest.mark.fail_slow(5)
1598
+ @pytest.mark.parametrize('exp_pow', ['exp', 'pow'])
1599
+ def test_exp_pow(self, exp_pow):
1600
+ rng = np.random.default_rng(81345982345826)
1601
+ mu = rng.random((3, 1))
1602
+ sigma = rng.random((3, 1))
1603
+
1604
+ X = Normal()*sigma + mu
1605
+ if exp_pow == 'exp':
1606
+ Y = stats.exp(X)
1607
+ else:
1608
+ Y = np.e ** X
1609
+ Y0 = stats.lognorm(sigma, scale=np.exp(mu))
1610
+
1611
+ y = Y0.rvs((3, 10), random_state=rng)
1612
+ p = Y0.cdf(y)
1613
+
1614
+ assert_allclose(Y.logentropy(), np.log(Y0.entropy()))
1615
+ assert_allclose(Y.entropy(), Y0.entropy())
1616
+ assert_allclose(Y.median(), Y0.ppf(0.5))
1617
+ assert_allclose(Y.mean(), Y0.mean())
1618
+ assert_allclose(Y.variance(), Y0.var())
1619
+ assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
1620
+ assert_allclose(Y.skewness(), Y0.stats('s'))
1621
+ assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
1622
+ assert_allclose(Y.support(), Y0.support())
1623
+ assert_allclose(Y.pdf(y), Y0.pdf(y))
1624
+ assert_allclose(Y.cdf(y), Y0.cdf(y))
1625
+ assert_allclose(Y.ccdf(y), Y0.sf(y))
1626
+ assert_allclose(Y.icdf(p), Y0.ppf(p))
1627
+ assert_allclose(Y.iccdf(p), Y0.isf(p))
1628
+ assert_allclose(Y.logpdf(y), Y0.logpdf(y))
1629
+ assert_allclose(Y.logcdf(y), Y0.logcdf(y))
1630
+ assert_allclose(Y.logccdf(y), Y0.logsf(y))
1631
+ assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
1632
+ assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
1633
+ seed = 3984593485
1634
+ assert_allclose(Y.sample(rng=seed), np.exp(X.sample(rng=seed)))
1635
+
1636
+
1637
+ @pytest.mark.fail_slow(10)
1638
+ @pytest.mark.parametrize('scale', [1, 2, -1])
1639
+ @pytest.mark.xfail_on_32bit("`scale=-1` fails on 32-bit; needs investigation")
1640
+ def test_reciprocal(self, scale):
1641
+ rng = np.random.default_rng(81345982345826)
1642
+ a = rng.random((3, 1))
1643
+
1644
+ # Separate sign from scale. It's easy to scale the resulting
1645
+ # RV with negative scale; we want to test the ability to divide
1646
+ # by a RV with negative support
1647
+ sign, scale = np.sign(scale), abs(scale)
1648
+
1649
+ # Reference distribution
1650
+ InvGamma = stats.make_distribution(stats.invgamma)
1651
+ Y0 = sign * scale * InvGamma(a=a)
1652
+
1653
+ # Test distribution
1654
+ X = _Gamma(a=a) if sign > 0 else -_Gamma(a=a)
1655
+ Y = scale / X
1656
+
1657
+ y = Y0.sample(shape=(3, 10), rng=rng)
1658
+ p = Y0.cdf(y)
1659
+ logp = np.log(p)
1660
+
1661
+ assert_allclose(Y.logentropy(), np.log(Y0.entropy()))
1662
+ assert_allclose(Y.entropy(), Y0.entropy())
1663
+ assert_allclose(Y.median(), Y0.median())
1664
+ # moments are not finite
1665
+ assert_allclose(Y.support(), Y0.support())
1666
+ assert_allclose(Y.pdf(y), Y0.pdf(y))
1667
+ assert_allclose(Y.cdf(y), Y0.cdf(y))
1668
+ assert_allclose(Y.ccdf(y), Y0.ccdf(y))
1669
+ assert_allclose(Y.icdf(p), Y0.icdf(p))
1670
+ assert_allclose(Y.iccdf(p), Y0.iccdf(p))
1671
+ assert_allclose(Y.logpdf(y), Y0.logpdf(y))
1672
+ assert_allclose(Y.logcdf(y), Y0.logcdf(y))
1673
+ assert_allclose(Y.logccdf(y), Y0.logccdf(y))
1674
+ with np.errstate(divide='ignore', invalid='ignore'):
1675
+ assert_allclose(Y.ilogcdf(logp), Y0.ilogcdf(logp))
1676
+ assert_allclose(Y.ilogccdf(logp), Y0.ilogccdf(logp))
1677
+ seed = 3984593485
1678
+ assert_allclose(Y.sample(rng=seed), scale/(X.sample(rng=seed)))
1679
+
1680
+ @pytest.mark.fail_slow(5)
1681
+ def test_log(self):
1682
+ rng = np.random.default_rng(81345982345826)
1683
+ a = rng.random((3, 1))
1684
+
1685
+ X = _Gamma(a=a)
1686
+ Y0 = stats.loggamma(a)
1687
+ Y = stats.log(X)
1688
+ y = Y0.rvs((3, 10), random_state=rng)
1689
+ p = Y0.cdf(y)
1690
+
1691
+ assert_allclose(Y.logentropy(), np.log(Y0.entropy()))
1692
+ assert_allclose(Y.entropy(), Y0.entropy())
1693
+ assert_allclose(Y.median(), Y0.ppf(0.5))
1694
+ assert_allclose(Y.mean(), Y0.mean())
1695
+ assert_allclose(Y.variance(), Y0.var())
1696
+ assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
1697
+ assert_allclose(Y.skewness(), Y0.stats('s'))
1698
+ assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
1699
+ assert_allclose(Y.support(), Y0.support())
1700
+ assert_allclose(Y.pdf(y), Y0.pdf(y))
1701
+ assert_allclose(Y.cdf(y), Y0.cdf(y))
1702
+ assert_allclose(Y.ccdf(y), Y0.sf(y))
1703
+ assert_allclose(Y.icdf(p), Y0.ppf(p))
1704
+ assert_allclose(Y.iccdf(p), Y0.isf(p))
1705
+ assert_allclose(Y.logpdf(y), Y0.logpdf(y))
1706
+ assert_allclose(Y.logcdf(y), Y0.logcdf(y))
1707
+ assert_allclose(Y.logccdf(y), Y0.logsf(y))
1708
+ with np.errstate(invalid='ignore'):
1709
+ assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
1710
+ assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
1711
+ seed = 3984593485
1712
+ assert_allclose(Y.sample(rng=seed), np.log(X.sample(rng=seed)))
1713
+
1714
+ def test_monotonic_transforms(self):
1715
+ # Some tests of monotonic transforms that are better to be grouped or
1716
+ # don't fit well above
1717
+
1718
+ X = Uniform(a=1, b=2)
1719
+ X_str = "Uniform(a=1.0, b=2.0)"
1720
+
1721
+ assert str(stats.log(X)) == f"log({X_str})"
1722
+ assert str(1 / X) == f"1/({X_str})"
1723
+ assert str(stats.exp(X)) == f"exp({X_str})"
1724
+
1725
+ X = Uniform(a=-1, b=2)
1726
+ message = "Division by a random variable is only implemented when the..."
1727
+ with pytest.raises(NotImplementedError, match=message):
1728
+ 1 / X
1729
+ message = "The logarithm of a random variable is only implemented when the..."
1730
+ with pytest.raises(NotImplementedError, match=message):
1731
+ stats.log(X)
1732
+ message = "Raising an argument to the power of a random variable is only..."
1733
+ with pytest.raises(NotImplementedError, match=message):
1734
+ (-2) ** X
1735
+ with pytest.raises(NotImplementedError, match=message):
1736
+ 1 ** X
1737
+ with pytest.raises(NotImplementedError, match=message):
1738
+ [0.5, 1.5] ** X
1739
+
1740
+ message = "Raising a random variable to the power of an argument is only"
1741
+ with pytest.raises(NotImplementedError, match=message):
1742
+ X ** (-2)
1743
+ with pytest.raises(NotImplementedError, match=message):
1744
+ X ** 0
1745
+ with pytest.raises(NotImplementedError, match=message):
1746
+ X ** [0.5, 1.5]
1747
+
1748
+ def test_arithmetic_operators(self):
1749
+ rng = np.random.default_rng(2348923495832349834)
1750
+
1751
+ a, b, loc, scale = 0.294, 1.34, 0.57, 1.16
1752
+
1753
+ x = rng.uniform(-3, 3, 100)
1754
+ Y = _LogUniform(a=a, b=b)
1755
+
1756
+ X = scale*Y + loc
1757
+ assert_allclose(X.cdf(x), Y.cdf((x - loc) / scale))
1758
+ X = loc + Y*scale
1759
+ assert_allclose(X.cdf(x), Y.cdf((x - loc) / scale))
1760
+
1761
+ X = Y/scale - loc
1762
+ assert_allclose(X.cdf(x), Y.cdf((x + loc) * scale))
1763
+ X = loc -_LogUniform(a=a, b=b)/scale
1764
+ assert_allclose(X.cdf(x), Y.ccdf((-x + loc)*scale))
1765
+
1766
+ def test_abs(self):
1767
+ rng = np.random.default_rng(81345982345826)
1768
+ loc = rng.random((3, 1))
1769
+
1770
+ Y = stats.abs(Normal() + loc)
1771
+ Y0 = stats.foldnorm(loc)
1772
+
1773
+ y = Y0.rvs((3, 10), random_state=rng)
1774
+ p = Y0.cdf(y)
1775
+
1776
+ assert_allclose(Y.logentropy(), np.log(Y0.entropy() + 0j))
1777
+ assert_allclose(Y.entropy(), Y0.entropy())
1778
+ assert_allclose(Y.median(), Y0.ppf(0.5))
1779
+ assert_allclose(Y.mean(), Y0.mean())
1780
+ assert_allclose(Y.variance(), Y0.var())
1781
+ assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
1782
+ assert_allclose(Y.skewness(), Y0.stats('s'))
1783
+ assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
1784
+ assert_allclose(Y.support(), Y0.support())
1785
+ assert_allclose(Y.pdf(y), Y0.pdf(y))
1786
+ assert_allclose(Y.cdf(y), Y0.cdf(y))
1787
+ assert_allclose(Y.ccdf(y), Y0.sf(y))
1788
+ assert_allclose(Y.icdf(p), Y0.ppf(p))
1789
+ assert_allclose(Y.iccdf(p), Y0.isf(p))
1790
+ assert_allclose(Y.logpdf(y), Y0.logpdf(y))
1791
+ assert_allclose(Y.logcdf(y), Y0.logcdf(y))
1792
+ assert_allclose(Y.logccdf(y), Y0.logsf(y))
1793
+ assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
1794
+ assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
1795
+ sample = Y.sample(10)
1796
+ assert np.all(sample > 0)
1797
+
1798
+ def test_abs_finite_support(self):
1799
+ # The original implementation of `FoldedDistribution` might evaluate
1800
+ # the private distribution methods outside the support. Check that this
1801
+ # is resolved.
1802
+ Weibull = stats.make_distribution(stats.weibull_min)
1803
+ X = Weibull(c=2)
1804
+ Y = abs(-X)
1805
+ assert_equal(X.logpdf(1), Y.logpdf(1))
1806
+ assert_equal(X.pdf(1), Y.pdf(1))
1807
+ assert_equal(X.logcdf(1), Y.logcdf(1))
1808
+ assert_equal(X.cdf(1), Y.cdf(1))
1809
+ assert_equal(X.logccdf(1), Y.logccdf(1))
1810
+ assert_equal(X.ccdf(1), Y.ccdf(1))
1811
+
1812
+ def test_pow(self):
1813
+ rng = np.random.default_rng(81345982345826)
1814
+
1815
+ Y = Normal()**2
1816
+ Y0 = stats.chi2(df=1)
1817
+
1818
+ y = Y0.rvs(10, random_state=rng)
1819
+ p = Y0.cdf(y)
1820
+
1821
+ assert_allclose(Y.logentropy(), np.log(Y0.entropy() + 0j), rtol=1e-6)
1822
+ assert_allclose(Y.entropy(), Y0.entropy(), rtol=1e-6)
1823
+ assert_allclose(Y.median(), Y0.median())
1824
+ assert_allclose(Y.mean(), Y0.mean())
1825
+ assert_allclose(Y.variance(), Y0.var())
1826
+ assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
1827
+ assert_allclose(Y.skewness(), Y0.stats('s'))
1828
+ assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
1829
+ assert_allclose(Y.support(), Y0.support())
1830
+ assert_allclose(Y.pdf(y), Y0.pdf(y))
1831
+ assert_allclose(Y.cdf(y), Y0.cdf(y))
1832
+ assert_allclose(Y.ccdf(y), Y0.sf(y))
1833
+ assert_allclose(Y.icdf(p), Y0.ppf(p))
1834
+ assert_allclose(Y.iccdf(p), Y0.isf(p))
1835
+ assert_allclose(Y.logpdf(y), Y0.logpdf(y))
1836
+ assert_allclose(Y.logcdf(y), Y0.logcdf(y))
1837
+ assert_allclose(Y.logccdf(y), Y0.logsf(y))
1838
+ assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
1839
+ assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
1840
+ sample = Y.sample(10)
1841
+ assert np.all(sample > 0)
1842
+
1843
+ class TestOrderStatistic:
1844
+ @pytest.mark.fail_slow(20) # Moments require integration
1845
+ def test_order_statistic(self):
1846
+ rng = np.random.default_rng(7546349802439582)
1847
+ X = Uniform(a=0, b=1)
1848
+ n = 5
1849
+ r = np.asarray([[1], [3], [5]])
1850
+ Y = stats.order_statistic(X, n=n, r=r)
1851
+ Y0 = stats.beta(r, n + 1 - r)
1852
+
1853
+ y = Y0.rvs((3, 10), random_state=rng)
1854
+ p = Y0.cdf(y)
1855
+
1856
+ # log methods need some attention before merge
1857
+ assert_allclose(np.exp(Y.logentropy()), Y0.entropy())
1858
+ assert_allclose(Y.entropy(), Y0.entropy())
1859
+ assert_allclose(Y.mean(), Y0.mean())
1860
+ assert_allclose(Y.variance(), Y0.var())
1861
+ assert_allclose(Y.skewness(), Y0.stats('s'), atol=1e-15)
1862
+ assert_allclose(Y.kurtosis(), Y0.stats('k') + 3, atol=1e-15)
1863
+ assert_allclose(Y.median(), Y0.ppf(0.5))
1864
+ assert_allclose(Y.support(), Y0.support())
1865
+ assert_allclose(Y.pdf(y), Y0.pdf(y))
1866
+ assert_allclose(Y.cdf(y, method='formula'), Y.cdf(y, method='quadrature'))
1867
+ assert_allclose(Y.ccdf(y, method='formula'), Y.ccdf(y, method='quadrature'))
1868
+ assert_allclose(Y.icdf(p, method='formula'), Y.icdf(p, method='inversion'))
1869
+ assert_allclose(Y.iccdf(p, method='formula'), Y.iccdf(p, method='inversion'))
1870
+ assert_allclose(Y.logpdf(y), Y0.logpdf(y))
1871
+ assert_allclose(Y.logcdf(y), Y0.logcdf(y))
1872
+ assert_allclose(Y.logccdf(y), Y0.logsf(y))
1873
+ with np.errstate(invalid='ignore', divide='ignore'):
1874
+ assert_allclose(Y.ilogcdf(np.log(p),), Y0.ppf(p))
1875
+ assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
1876
+
1877
+ message = "`r` and `n` must contain only positive integers."
1878
+ with pytest.raises(ValueError, match=message):
1879
+ stats.order_statistic(X, n=n, r=-1)
1880
+ with pytest.raises(ValueError, match=message):
1881
+ stats.order_statistic(X, n=-1, r=r)
1882
+ with pytest.raises(ValueError, match=message):
1883
+ stats.order_statistic(X, n=n, r=1.5)
1884
+ with pytest.raises(ValueError, match=message):
1885
+ stats.order_statistic(X, n=1.5, r=r)
1886
+
1887
+ def test_support_gh22037(self):
1888
+ # During review of gh-22037, it was noted that the `support` of
1889
+ # an `OrderStatisticDistribution` returned incorrect results;
1890
+ # this was resolved by overriding `_support`.
1891
+ Uniform = stats.make_distribution(stats.uniform)
1892
+ X = Uniform()
1893
+ Y = X*5 + 2
1894
+ Z = stats.order_statistic(Y, r=3, n=5)
1895
+ assert_allclose(Z.support(), Y.support())
1896
+
1897
+ def test_composition_gh22037(self):
1898
+ # During review of gh-22037, it was noted that an error was
1899
+ # raised when creating an `OrderStatisticDistribution` from
1900
+ # a `TruncatedDistribution`. This was resolved by overriding
1901
+ # `_update_parameters`.
1902
+ Normal = stats.make_distribution(stats.norm)
1903
+ TruncatedNormal = stats.make_distribution(stats.truncnorm)
1904
+ a, b = [-2, -1], 1
1905
+ r, n = 3, [[4], [5]]
1906
+ x = [[[-0.3]], [[0.1]]]
1907
+ X1 = Normal()
1908
+ Y1 = stats.truncate(X1, a, b)
1909
+ Z1 = stats.order_statistic(Y1, r=r, n=n)
1910
+ X2 = TruncatedNormal(a=a, b=b)
1911
+ Z2 = stats.order_statistic(X2, r=r, n=n)
1912
+ np.testing.assert_allclose(Z1.cdf(x), Z2.cdf(x))
1913
+
1914
+
1915
+ class TestFullCoverage:
1916
+ # Adds tests just to get to 100% test coverage; this way it's more obvious
1917
+ # if new lines are untested.
1918
+ def test_Domain(self):
1919
+ with pytest.raises(NotImplementedError):
1920
+ _Domain.contains(None, 1.)
1921
+ with pytest.raises(NotImplementedError):
1922
+ _Domain.get_numerical_endpoints(None, 1.)
1923
+ with pytest.raises(NotImplementedError):
1924
+ _Domain.__str__(None)
1925
+
1926
+ def test_Parameter(self):
1927
+ with pytest.raises(NotImplementedError):
1928
+ _Parameter.validate(None, 1.)
1929
+
1930
+ @pytest.mark.parametrize(("dtype_in", "dtype_out"),
1931
+ [(np.float16, np.float16),
1932
+ (np.int16, np.float64)])
1933
+ def test_RealParameter_uncommon_dtypes(self, dtype_in, dtype_out):
1934
+ domain = _RealInterval((-1, 1))
1935
+ parameter = _RealParameter('x', domain=domain)
1936
+
1937
+ x = np.asarray([0.5, 2.5], dtype=dtype_in)
1938
+ arr, dtype, valid = parameter.validate(x, parameter_values={})
1939
+ assert_equal(arr, x)
1940
+ assert dtype == dtype_out
1941
+ assert_equal(valid, [True, False])
1942
+
1943
+ def test_ContinuousDistribution_set_invalid_nan(self):
1944
+ # Exercise code paths when formula returns wrong shape and dtype
1945
+ # We could consider making this raise an error to force authors
1946
+ # to return the right shape and dytpe, but this would need to be
1947
+ # configurable.
1948
+ class TestDist(ContinuousDistribution):
1949
+ _variable = _RealParameter('x', domain=_RealInterval(endpoints=(0., 1.)))
1950
+ def _logpdf_formula(self, x, *args, **kwargs):
1951
+ return 0
1952
+
1953
+ X = TestDist()
1954
+ dtype = np.float32
1955
+ X._dtype = dtype
1956
+ x = np.asarray([0.5], dtype=dtype)
1957
+ assert X.logpdf(x).dtype == dtype
1958
+
1959
+ def test_fiinfo(self):
1960
+ assert _fiinfo(np.float64(1.)).max == np.finfo(np.float64).max
1961
+ assert _fiinfo(np.int64(1)).max == np.iinfo(np.int64).max
1962
+
1963
+ def test_generate_domain_support(self):
1964
+ msg = _generate_domain_support(StandardNormal)
1965
+ assert "accepts no distribution parameters" in msg
1966
+
1967
+ msg = _generate_domain_support(Normal)
1968
+ assert "accepts one parameterization" in msg
1969
+
1970
+ msg = _generate_domain_support(_LogUniform)
1971
+ assert "accepts two parameterizations" in msg
1972
+
1973
+ def test_ContinuousDistribution__repr__(self):
1974
+ X = Uniform(a=0, b=1)
1975
+ if np.__version__ < "2":
1976
+ assert repr(X) == "Uniform(a=0.0, b=1.0)"
1977
+ else:
1978
+ assert repr(X) == "Uniform(a=np.float64(0.0), b=np.float64(1.0))"
1979
+ if np.__version__ < "2":
1980
+ assert repr(X*3 + 2) == "3.0*Uniform(a=0.0, b=1.0) + 2.0"
1981
+ else:
1982
+ assert repr(X*3 + 2) == (
1983
+ "np.float64(3.0)*Uniform(a=np.float64(0.0), b=np.float64(1.0))"
1984
+ " + np.float64(2.0)"
1985
+ )
1986
+
1987
+ X = Uniform(a=np.zeros(4), b=1)
1988
+ assert repr(X) == "Uniform(a=array([0., 0., 0., 0.]), b=1)"
1989
+
1990
+ X = Uniform(a=np.zeros(4, dtype=np.float32), b=np.ones(4, dtype=np.float32))
1991
+ assert repr(X) == (
1992
+ "Uniform(a=array([0., 0., 0., 0.], dtype=float32),"
1993
+ " b=array([1., 1., 1., 1.], dtype=float32))"
1994
+ )
1995
+
1996
+
1997
+ class TestReprs:
1998
+ U = Uniform(a=0, b=1)
1999
+ V = Uniform(a=np.float32(0.0), b=np.float32(1.0))
2000
+ X = Normal(mu=-1, sigma=1)
2001
+ Y = Normal(mu=1, sigma=1)
2002
+ Z = Normal(mu=np.zeros(1000), sigma=1)
2003
+
2004
+ @pytest.mark.parametrize(
2005
+ "dist",
2006
+ [
2007
+ U,
2008
+ U - np.array([1.0, 2.0]),
2009
+ pytest.param(
2010
+ V,
2011
+ marks=pytest.mark.skipif(
2012
+ np.__version__ < "2",
2013
+ reason="numpy 1.x didn't have dtype in repr",
2014
+ )
2015
+ ),
2016
+ pytest.param(
2017
+ np.ones(2, dtype=np.float32)*V + np.zeros(2, dtype=np.float64),
2018
+ marks=pytest.mark.skipif(
2019
+ np.__version__ < "2",
2020
+ reason="numpy 1.x didn't have dtype in repr",
2021
+ )
2022
+ ),
2023
+ 3*U + 2,
2024
+ U**4,
2025
+ (3*U + 2)**4,
2026
+ (3*U + 2)**3,
2027
+ 2**U,
2028
+ 2**(3*U + 1),
2029
+ 1 / (1 + U),
2030
+ stats.order_statistic(U, r=3, n=5),
2031
+ stats.truncate(U, 0.2, 0.8),
2032
+ stats.Mixture([X, Y], weights=[0.3, 0.7]),
2033
+ abs(U),
2034
+ stats.exp(U),
2035
+ stats.log(1 + U),
2036
+ np.array([1.0, 2.0])*U + np.array([2.0, 3.0]),
2037
+ ]
2038
+ )
2039
+ def test_executable(self, dist):
2040
+ # Test that reprs actually evaluate to proper distribution
2041
+ # provided relevant imports are made.
2042
+ from numpy import array # noqa: F401
2043
+ from numpy import float32 # noqa: F401
2044
+ from scipy.stats import abs, exp, log, order_statistic, truncate # noqa: F401
2045
+ from scipy.stats import Mixture, Normal # noqa: F401
2046
+ from scipy.stats._new_distributions import Uniform # noqa: F401
2047
+ new_dist = eval(repr(dist))
2048
+ # A basic check that the distributions are the same
2049
+ sample1 = dist.sample(shape=10, rng=1234)
2050
+ sample2 = new_dist.sample(shape=10, rng=1234)
2051
+ assert_equal(sample1, sample2)
2052
+ assert sample1.dtype is sample2.dtype
2053
+
2054
+ @pytest.mark.parametrize(
2055
+ "dist",
2056
+ [
2057
+ Z,
2058
+ np.full(1000, 2.0) * X + 1.0,
2059
+ 2.0 * X + np.full(1000, 1.0),
2060
+ np.full(1000, 2.0) * X + 1.0,
2061
+ stats.truncate(Z, -1, 1),
2062
+ stats.truncate(Z, -np.ones(1000), np.ones(1000)),
2063
+ stats.order_statistic(X, r=np.arange(1, 1000), n=1000),
2064
+ Z**2,
2065
+ 1.0 / (1 + stats.exp(Z)),
2066
+ 2**Z,
2067
+ ]
2068
+ )
2069
+ def test_not_too_long(self, dist):
2070
+ # Tests that array summarization is working to ensure reprs aren't too long.
2071
+ # None of the reprs above will be executable.
2072
+ assert len(repr(dist)) < 250
2073
+
2074
+
2075
+ class MixedDist(ContinuousDistribution):
2076
+ _variable = _RealParameter('x', domain=_RealInterval(endpoints=(-np.inf, np.inf)))
2077
+ def _pdf_formula(self, x, *args, **kwargs):
2078
+ return (0.4 * 1/(1.1 * np.sqrt(2*np.pi)) * np.exp(-0.5*((x+0.25)/1.1)**2)
2079
+ + 0.6 * 1/(0.9 * np.sqrt(2*np.pi)) * np.exp(-0.5*((x-0.5)/0.9)**2))
2080
+
2081
+
2082
+ class TestMixture:
2083
+ def test_input_validation(self):
2084
+ message = "`components` must contain at least one random variable."
2085
+ with pytest.raises(ValueError, match=message):
2086
+ Mixture([])
2087
+
2088
+ message = "Each element of `components` must be an instance..."
2089
+ with pytest.raises(ValueError, match=message):
2090
+ Mixture((1, 2, 3))
2091
+
2092
+ message = "All elements of `components` must have scalar shapes."
2093
+ with pytest.raises(ValueError, match=message):
2094
+ Mixture([Normal(mu=[1, 2]), Normal()])
2095
+
2096
+ message = "`components` and `weights` must have the same length."
2097
+ with pytest.raises(ValueError, match=message):
2098
+ Mixture([Normal()], weights=[0.5, 0.5])
2099
+
2100
+ message = "`weights` must have floating point dtype."
2101
+ with pytest.raises(ValueError, match=message):
2102
+ Mixture([Normal()], weights=[1])
2103
+
2104
+ message = "`weights` must have floating point dtype."
2105
+ with pytest.raises(ValueError, match=message):
2106
+ Mixture([Normal()], weights=[1])
2107
+
2108
+ message = "`weights` must sum to 1.0."
2109
+ with pytest.raises(ValueError, match=message):
2110
+ Mixture([Normal(), Normal()], weights=[0.5, 1.0])
2111
+
2112
+ message = "All `weights` must be non-negative."
2113
+ with pytest.raises(ValueError, match=message):
2114
+ Mixture([Normal(), Normal()], weights=[1.5, -0.5])
2115
+
2116
+ @pytest.mark.parametrize('shape', [(), (10,)])
2117
+ def test_basic(self, shape):
2118
+ rng = np.random.default_rng(582348972387243524)
2119
+ X = Mixture((Normal(mu=-0.25, sigma=1.1), Normal(mu=0.5, sigma=0.9)),
2120
+ weights=(0.4, 0.6))
2121
+ Y = MixedDist()
2122
+ x = rng.random(shape)
2123
+
2124
+ def assert_allclose(res, ref, **kwargs):
2125
+ if shape == ():
2126
+ assert np.isscalar(res)
2127
+ np.testing.assert_allclose(res, ref, **kwargs)
2128
+
2129
+ assert_allclose(X.logentropy(), Y.logentropy())
2130
+ assert_allclose(X.entropy(), Y.entropy())
2131
+ assert_allclose(X.mode(), Y.mode())
2132
+ assert_allclose(X.median(), Y.median())
2133
+ assert_allclose(X.mean(), Y.mean())
2134
+ assert_allclose(X.variance(), Y.variance())
2135
+ assert_allclose(X.standard_deviation(), Y.standard_deviation())
2136
+ assert_allclose(X.skewness(), Y.skewness())
2137
+ assert_allclose(X.kurtosis(), Y.kurtosis())
2138
+ assert_allclose(X.logpdf(x), Y.logpdf(x))
2139
+ assert_allclose(X.pdf(x), Y.pdf(x))
2140
+ assert_allclose(X.logcdf(x), Y.logcdf(x))
2141
+ assert_allclose(X.cdf(x), Y.cdf(x))
2142
+ assert_allclose(X.logccdf(x), Y.logccdf(x))
2143
+ assert_allclose(X.ccdf(x), Y.ccdf(x))
2144
+ assert_allclose(X.ilogcdf(x), Y.ilogcdf(x))
2145
+ assert_allclose(X.icdf(x), Y.icdf(x))
2146
+ assert_allclose(X.ilogccdf(x), Y.ilogccdf(x))
2147
+ assert_allclose(X.iccdf(x), Y.iccdf(x))
2148
+ for kind in ['raw', 'central', 'standardized']:
2149
+ for order in range(5):
2150
+ assert_allclose(X.moment(order, kind=kind),
2151
+ Y.moment(order, kind=kind),
2152
+ atol=1e-15)
2153
+
2154
+ # weak test of `sample`
2155
+ shape = (10, 20, 5)
2156
+ y = X.sample(shape, rng=rng)
2157
+ assert y.shape == shape
2158
+ assert stats.ks_1samp(y.ravel(), X.cdf).pvalue > 0.05
2159
+
2160
+ def test_default_weights(self):
2161
+ a = 1.1
2162
+ Gamma = stats.make_distribution(stats.gamma)
2163
+ X = Gamma(a=a)
2164
+ Y = stats.Mixture((X, -X))
2165
+ x = np.linspace(-4, 4, 300)
2166
+ assert_allclose(Y.pdf(x), stats.dgamma(a=a).pdf(x))
2167
+
2168
+ def test_properties(self):
2169
+ components = [Normal(mu=-0.25, sigma=1.1), Normal(mu=0.5, sigma=0.9)]
2170
+ weights = (0.4, 0.6)
2171
+ X = Mixture(components, weights=weights)
2172
+
2173
+ # Replacing properties doesn't work
2174
+ # Different version of Python have different messages
2175
+ with pytest.raises(AttributeError):
2176
+ X.components = 10
2177
+ with pytest.raises(AttributeError):
2178
+ X.weights = 10
2179
+
2180
+ # Mutation doesn't work
2181
+ X.components[0] = components[1]
2182
+ assert X.components[0] == components[0]
2183
+ X.weights[0] = weights[1]
2184
+ assert X.weights[0] == weights[0]
2185
+
2186
+ def test_inverse(self):
2187
+ # Originally, inverse relied on the mean to start the bracket search.
2188
+ # This didn't work for distributions with non-finite mean. Check that
2189
+ # this is resolved.
2190
+ rng = np.random.default_rng(24358934657854237863456)
2191
+ Cauchy = stats.make_distribution(stats.cauchy)
2192
+ X0 = Cauchy()
2193
+ X = stats.Mixture([X0, X0])
2194
+ p = rng.random(size=10)
2195
+ np.testing.assert_allclose(X.icdf(p), X0.icdf(p))
2196
+ np.testing.assert_allclose(X.iccdf(p), X0.iccdf(p))
2197
+ np.testing.assert_allclose(X.ilogcdf(p), X0.ilogcdf(p))
2198
+ np.testing.assert_allclose(X.ilogccdf(p), X0.ilogccdf(p))