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,2000 @@
1
+ import pytest
2
+
3
+ import numpy as np
4
+ from numpy.testing import assert_allclose, assert_equal, suppress_warnings
5
+
6
+ from scipy._lib._util import rng_integers
7
+ from scipy._lib._array_api import is_numpy
8
+ from scipy._lib._array_api_no_0d import xp_assert_close, xp_assert_equal
9
+ from scipy import stats, special
10
+ from scipy.optimize import root
11
+
12
+ from scipy.stats import bootstrap, monte_carlo_test, permutation_test, power
13
+ import scipy.stats._resampling as _resampling
14
+
15
+
16
+ def test_bootstrap_iv():
17
+
18
+ message = "`data` must be a sequence of samples."
19
+ with pytest.raises(ValueError, match=message):
20
+ bootstrap(1, np.mean)
21
+
22
+ message = "`data` must contain at least one sample."
23
+ with pytest.raises(ValueError, match=message):
24
+ bootstrap(tuple(), np.mean)
25
+
26
+ message = "each sample in `data` must contain two or more observations..."
27
+ with pytest.raises(ValueError, match=message):
28
+ bootstrap(([1, 2, 3], [1]), np.mean)
29
+
30
+ message = ("When `paired is True`, all samples must have the same length ")
31
+ with pytest.raises(ValueError, match=message):
32
+ bootstrap(([1, 2, 3], [1, 2, 3, 4]), np.mean, paired=True)
33
+
34
+ message = "`vectorized` must be `True`, `False`, or `None`."
35
+ with pytest.raises(ValueError, match=message):
36
+ bootstrap(1, np.mean, vectorized='ekki')
37
+
38
+ message = "`axis` must be an integer."
39
+ with pytest.raises(ValueError, match=message):
40
+ bootstrap(([1, 2, 3],), np.mean, axis=1.5)
41
+
42
+ message = "could not convert string to float"
43
+ with pytest.raises(ValueError, match=message):
44
+ bootstrap(([1, 2, 3],), np.mean, confidence_level='ni')
45
+
46
+ message = "`n_resamples` must be a non-negative integer."
47
+ with pytest.raises(ValueError, match=message):
48
+ bootstrap(([1, 2, 3],), np.mean, n_resamples=-1000)
49
+
50
+ message = "`n_resamples` must be a non-negative integer."
51
+ with pytest.raises(ValueError, match=message):
52
+ bootstrap(([1, 2, 3],), np.mean, n_resamples=1000.5)
53
+
54
+ message = "`batch` must be a positive integer or None."
55
+ with pytest.raises(ValueError, match=message):
56
+ bootstrap(([1, 2, 3],), np.mean, batch=-1000)
57
+
58
+ message = "`batch` must be a positive integer or None."
59
+ with pytest.raises(ValueError, match=message):
60
+ bootstrap(([1, 2, 3],), np.mean, batch=1000.5)
61
+
62
+ message = "`method` must be in"
63
+ with pytest.raises(ValueError, match=message):
64
+ bootstrap(([1, 2, 3],), np.mean, method='ekki')
65
+
66
+ message = "`bootstrap_result` must have attribute `bootstrap_distribution'"
67
+ with pytest.raises(ValueError, match=message):
68
+ bootstrap(([1, 2, 3],), np.mean, bootstrap_result=10)
69
+
70
+ message = "Either `bootstrap_result.bootstrap_distribution.size`"
71
+ with pytest.raises(ValueError, match=message):
72
+ bootstrap(([1, 2, 3],), np.mean, n_resamples=0)
73
+
74
+ message = "SeedSequence expects int or sequence of ints"
75
+ with pytest.raises(TypeError, match=message):
76
+ bootstrap(([1, 2, 3],), np.mean, rng='herring')
77
+
78
+
79
+ @pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
80
+ @pytest.mark.parametrize("axis", [0, 1, 2])
81
+ def test_bootstrap_batch(method, axis):
82
+ # for one-sample statistics, batch size shouldn't affect the result
83
+ rng = np.random.RandomState(0)
84
+
85
+ x = rng.rand(10, 11, 12)
86
+ # SPEC-007 leave one call with random_state to ensure it still works
87
+ res1 = bootstrap((x,), np.mean, batch=None, method=method,
88
+ random_state=0, axis=axis, n_resamples=100)
89
+ rng = np.random.RandomState(0)
90
+ res2 = bootstrap((x,), np.mean, batch=10, method=method,
91
+ axis=axis, n_resamples=100, random_state=rng)
92
+
93
+ assert_equal(res2.confidence_interval.low, res1.confidence_interval.low)
94
+ assert_equal(res2.confidence_interval.high, res1.confidence_interval.high)
95
+ assert_equal(res2.standard_error, res1.standard_error)
96
+
97
+
98
+ @pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
99
+ def test_bootstrap_paired(method):
100
+ # test that `paired` works as expected
101
+ rng = np.random.RandomState(0)
102
+ n = 100
103
+ x = rng.rand(n)
104
+ y = rng.rand(n)
105
+
106
+ def my_statistic(x, y, axis=-1):
107
+ return ((x-y)**2).mean(axis=axis)
108
+
109
+ def my_paired_statistic(i, axis=-1):
110
+ a = x[i]
111
+ b = y[i]
112
+ res = my_statistic(a, b)
113
+ return res
114
+
115
+ i = np.arange(len(x))
116
+
117
+ res1 = bootstrap((i,), my_paired_statistic, rng=0)
118
+ res2 = bootstrap((x, y), my_statistic, paired=True, rng=0)
119
+
120
+ assert_allclose(res1.confidence_interval, res2.confidence_interval)
121
+ assert_allclose(res1.standard_error, res2.standard_error)
122
+
123
+
124
+ @pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
125
+ @pytest.mark.parametrize("axis", [0, 1, 2])
126
+ @pytest.mark.parametrize("paired", [True, False])
127
+ def test_bootstrap_vectorized(method, axis, paired):
128
+ # test that paired is vectorized as expected: when samples are tiled,
129
+ # CI and standard_error of each axis-slice is the same as those of the
130
+ # original 1d sample
131
+
132
+ rng = np.random.RandomState(0)
133
+
134
+ def my_statistic(x, y, z, axis=-1):
135
+ return x.mean(axis=axis) + y.mean(axis=axis) + z.mean(axis=axis)
136
+
137
+ shape = 10, 11, 12
138
+ n_samples = shape[axis]
139
+
140
+ x = rng.rand(n_samples)
141
+ y = rng.rand(n_samples)
142
+ z = rng.rand(n_samples)
143
+ res1 = bootstrap((x, y, z), my_statistic, paired=paired, method=method,
144
+ rng=0, axis=0, n_resamples=100)
145
+ assert (res1.bootstrap_distribution.shape
146
+ == res1.standard_error.shape + (100,))
147
+
148
+ reshape = [1, 1, 1]
149
+ reshape[axis] = n_samples
150
+ x = np.broadcast_to(x.reshape(reshape), shape)
151
+ y = np.broadcast_to(y.reshape(reshape), shape)
152
+ z = np.broadcast_to(z.reshape(reshape), shape)
153
+ res2 = bootstrap((x, y, z), my_statistic, paired=paired, method=method,
154
+ rng=0, axis=axis, n_resamples=100)
155
+
156
+ assert_allclose(res2.confidence_interval.low,
157
+ res1.confidence_interval.low)
158
+ assert_allclose(res2.confidence_interval.high,
159
+ res1.confidence_interval.high)
160
+ assert_allclose(res2.standard_error, res1.standard_error)
161
+
162
+ result_shape = list(shape)
163
+ result_shape.pop(axis)
164
+
165
+ assert_equal(res2.confidence_interval.low.shape, result_shape)
166
+ assert_equal(res2.confidence_interval.high.shape, result_shape)
167
+ assert_equal(res2.standard_error.shape, result_shape)
168
+
169
+
170
+ @pytest.mark.slow
171
+ @pytest.mark.xfail_on_32bit("MemoryError with BCa observed in CI")
172
+ @pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
173
+ def test_bootstrap_against_theory(method):
174
+ # based on https://www.statology.org/confidence-intervals-python/
175
+ rng = np.random.default_rng(2442101192988600726)
176
+ data = stats.norm.rvs(loc=5, scale=2, size=5000, random_state=rng)
177
+ alpha = 0.95
178
+ dist = stats.t(df=len(data)-1, loc=np.mean(data), scale=stats.sem(data))
179
+ expected_interval = dist.interval(confidence=alpha)
180
+ expected_se = dist.std()
181
+
182
+ config = dict(data=(data,), statistic=np.mean, n_resamples=5000,
183
+ method=method, rng=rng)
184
+ res = bootstrap(**config, confidence_level=alpha)
185
+ assert_allclose(res.confidence_interval, expected_interval, rtol=5e-4)
186
+ assert_allclose(res.standard_error, expected_se, atol=3e-4)
187
+
188
+ config.update(dict(n_resamples=0, bootstrap_result=res))
189
+ res = bootstrap(**config, confidence_level=alpha, alternative='less')
190
+ assert_allclose(res.confidence_interval.high, dist.ppf(alpha), rtol=5e-4)
191
+
192
+ config.update(dict(n_resamples=0, bootstrap_result=res))
193
+ res = bootstrap(**config, confidence_level=alpha, alternative='greater')
194
+ assert_allclose(res.confidence_interval.low, dist.ppf(1-alpha), rtol=5e-4)
195
+
196
+
197
+ tests_R = {"basic": (23.77, 79.12),
198
+ "percentile": (28.86, 84.21),
199
+ "BCa": (32.31, 91.43)}
200
+
201
+
202
+ @pytest.mark.parametrize("method, expected", tests_R.items())
203
+ def test_bootstrap_against_R(method, expected):
204
+ # Compare against R's "boot" library
205
+ # library(boot)
206
+
207
+ # stat <- function (x, a) {
208
+ # mean(x[a])
209
+ # }
210
+
211
+ # x <- c(10, 12, 12.5, 12.5, 13.9, 15, 21, 22,
212
+ # 23, 34, 50, 81, 89, 121, 134, 213)
213
+
214
+ # # Use a large value so we get a few significant digits for the CI.
215
+ # n = 1000000
216
+ # bootresult = boot(x, stat, n)
217
+ # result <- boot.ci(bootresult)
218
+ # print(result)
219
+ x = np.array([10, 12, 12.5, 12.5, 13.9, 15, 21, 22,
220
+ 23, 34, 50, 81, 89, 121, 134, 213])
221
+ res = bootstrap((x,), np.mean, n_resamples=1000000, method=method,
222
+ rng=0)
223
+ assert_allclose(res.confidence_interval, expected, rtol=0.005)
224
+
225
+
226
+ def test_multisample_BCa_against_R():
227
+ # Because bootstrap is stochastic, it's tricky to test against reference
228
+ # behavior. Here, we show that SciPy's BCa CI matches R wboot's BCa CI
229
+ # much more closely than the other SciPy CIs do.
230
+
231
+ # arbitrary skewed data
232
+ x = [0.75859206, 0.5910282, -0.4419409, -0.36654601,
233
+ 0.34955357, -1.38835871, 0.76735821]
234
+ y = [1.41186073, 0.49775975, 0.08275588, 0.24086388,
235
+ 0.03567057, 0.52024419, 0.31966611, 1.32067634]
236
+
237
+ # a multi-sample statistic for which the BCa CI tends to be different
238
+ # from the other CIs
239
+ def statistic(x, y, axis):
240
+ s1 = stats.skew(x, axis=axis)
241
+ s2 = stats.skew(y, axis=axis)
242
+ return s1 - s2
243
+
244
+ # compute confidence intervals using each method
245
+ rng = np.random.default_rng(468865032284792692)
246
+
247
+ res_basic = stats.bootstrap((x, y), statistic, method='basic',
248
+ batch=100, rng=rng)
249
+ res_percent = stats.bootstrap((x, y), statistic, method='percentile',
250
+ batch=100, rng=rng)
251
+ res_bca = stats.bootstrap((x, y), statistic, method='bca',
252
+ batch=100, rng=rng)
253
+
254
+ # compute midpoints so we can compare just one number for each
255
+ mid_basic = np.mean(res_basic.confidence_interval)
256
+ mid_percent = np.mean(res_percent.confidence_interval)
257
+ mid_bca = np.mean(res_bca.confidence_interval)
258
+
259
+ # reference for BCA CI computed using R wboot package:
260
+ # library(wBoot)
261
+ # library(moments)
262
+
263
+ # x = c(0.75859206, 0.5910282, -0.4419409, -0.36654601,
264
+ # 0.34955357, -1.38835871, 0.76735821)
265
+ # y = c(1.41186073, 0.49775975, 0.08275588, 0.24086388,
266
+ # 0.03567057, 0.52024419, 0.31966611, 1.32067634)
267
+
268
+ # twoskew <- function(x1, y1) {skewness(x1) - skewness(y1)}
269
+ # boot.two.bca(x, y, skewness, conf.level = 0.95,
270
+ # R = 9999, stacked = FALSE)
271
+ mid_wboot = -1.5519
272
+
273
+ # compute percent difference relative to wboot BCA method
274
+ diff_basic = (mid_basic - mid_wboot)/abs(mid_wboot)
275
+ diff_percent = (mid_percent - mid_wboot)/abs(mid_wboot)
276
+ diff_bca = (mid_bca - mid_wboot)/abs(mid_wboot)
277
+
278
+ # SciPy's BCa CI midpoint is much closer than that of the other methods
279
+ assert diff_basic < -0.15
280
+ assert diff_percent > 0.15
281
+ assert abs(diff_bca) < 0.03
282
+
283
+
284
+ def test_BCa_acceleration_against_reference():
285
+ # Compare the (deterministic) acceleration parameter for a multi-sample
286
+ # problem against a reference value. The example is from [1], but Efron's
287
+ # value seems inaccurate. Straightforward code for computing the
288
+ # reference acceleration (0.011008228344026734) is available at:
289
+ # https://github.com/scipy/scipy/pull/16455#issuecomment-1193400981
290
+
291
+ y = np.array([10, 27, 31, 40, 46, 50, 52, 104, 146])
292
+ z = np.array([16, 23, 38, 94, 99, 141, 197])
293
+
294
+ def statistic(z, y, axis=0):
295
+ return np.mean(z, axis=axis) - np.mean(y, axis=axis)
296
+
297
+ data = [z, y]
298
+ res = stats.bootstrap(data, statistic)
299
+
300
+ axis = -1
301
+ alpha = 0.95
302
+ theta_hat_b = res.bootstrap_distribution
303
+ batch = 100
304
+ _, _, a_hat = _resampling._bca_interval(data, statistic, axis, alpha,
305
+ theta_hat_b, batch)
306
+ assert_allclose(a_hat, 0.011008228344026734)
307
+
308
+
309
+ tests_against_itself_1samp = {"basic": 1789,
310
+ "percentile": 1790,
311
+ "BCa": 1789}
312
+
313
+
314
+ @pytest.mark.slow
315
+ @pytest.mark.parametrize("method, expected",
316
+ tests_against_itself_1samp.items())
317
+ def test_bootstrap_against_itself_1samp(method, expected):
318
+ # The expected values in this test were generated using bootstrap
319
+ # to check for unintended changes in behavior. The test also makes sure
320
+ # that bootstrap works with multi-sample statistics and that the
321
+ # `axis` argument works as expected / function is vectorized.
322
+ rng = np.random.default_rng(9123847)
323
+
324
+ n = 100 # size of sample
325
+ n_resamples = 999 # number of bootstrap resamples used to form each CI
326
+ confidence_level = 0.9
327
+
328
+ # The true mean is 5
329
+ dist = stats.norm(loc=5, scale=1)
330
+ stat_true = dist.mean()
331
+
332
+ # Do the same thing 2000 times. (The code is fully vectorized.)
333
+ n_replications = 2000
334
+ data = dist.rvs(size=(n_replications, n), random_state=rng)
335
+ res = bootstrap((data,),
336
+ statistic=np.mean,
337
+ confidence_level=confidence_level,
338
+ n_resamples=n_resamples,
339
+ batch=50,
340
+ method=method,
341
+ axis=-1,
342
+ rng=rng)
343
+ ci = res.confidence_interval
344
+
345
+ # ci contains vectors of lower and upper confidence interval bounds
346
+ ci_contains_true = np.sum((ci[0] < stat_true) & (stat_true < ci[1]))
347
+ assert ci_contains_true == expected
348
+
349
+ # ci_contains_true is not inconsistent with confidence_level
350
+ pvalue = stats.binomtest(ci_contains_true, n_replications,
351
+ confidence_level).pvalue
352
+ assert pvalue > 0.1
353
+
354
+
355
+ tests_against_itself_2samp = {"basic": 892,
356
+ "percentile": 890}
357
+
358
+
359
+ @pytest.mark.slow
360
+ @pytest.mark.parametrize("method, expected",
361
+ tests_against_itself_2samp.items())
362
+ def test_bootstrap_against_itself_2samp(method, expected):
363
+ # The expected values in this test were generated using bootstrap
364
+ # to check for unintended changes in behavior. The test also makes sure
365
+ # that bootstrap works with multi-sample statistics and that the
366
+ # `axis` argument works as expected / function is vectorized.
367
+ rng = np.random.RandomState(0)
368
+
369
+ n1 = 100 # size of sample 1
370
+ n2 = 120 # size of sample 2
371
+ n_resamples = 999 # number of bootstrap resamples used to form each CI
372
+ confidence_level = 0.9
373
+
374
+ # The statistic we're interested in is the difference in means
375
+ def my_stat(data1, data2, axis=-1):
376
+ mean1 = np.mean(data1, axis=axis)
377
+ mean2 = np.mean(data2, axis=axis)
378
+ return mean1 - mean2
379
+
380
+ # The true difference in the means is -0.1
381
+ dist1 = stats.norm(loc=0, scale=1)
382
+ dist2 = stats.norm(loc=0.1, scale=1)
383
+ stat_true = dist1.mean() - dist2.mean()
384
+
385
+ # Do the same thing 1000 times. (The code is fully vectorized.)
386
+ n_replications = 1000
387
+ data1 = dist1.rvs(size=(n_replications, n1), random_state=rng)
388
+ data2 = dist2.rvs(size=(n_replications, n2), random_state=rng)
389
+ res = bootstrap((data1, data2),
390
+ statistic=my_stat,
391
+ confidence_level=confidence_level,
392
+ n_resamples=n_resamples,
393
+ batch=50,
394
+ method=method,
395
+ axis=-1,
396
+ random_state=rng)
397
+ ci = res.confidence_interval
398
+
399
+ # ci contains vectors of lower and upper confidence interval bounds
400
+ ci_contains_true = np.sum((ci[0] < stat_true) & (stat_true < ci[1]))
401
+ assert ci_contains_true == expected
402
+
403
+ # ci_contains_true is not inconsistent with confidence_level
404
+ pvalue = stats.binomtest(ci_contains_true, n_replications,
405
+ confidence_level).pvalue
406
+ assert pvalue > 0.1
407
+
408
+
409
+ @pytest.mark.parametrize("method", ["basic", "percentile"])
410
+ @pytest.mark.parametrize("axis", [0, 1])
411
+ def test_bootstrap_vectorized_3samp(method, axis):
412
+ def statistic(*data, axis=0):
413
+ # an arbitrary, vectorized statistic
414
+ return sum(sample.mean(axis) for sample in data)
415
+
416
+ def statistic_1d(*data):
417
+ # the same statistic, not vectorized
418
+ for sample in data:
419
+ assert sample.ndim == 1
420
+ return statistic(*data, axis=0)
421
+
422
+ rng = np.random.RandomState(0)
423
+ x = rng.rand(4, 5)
424
+ y = rng.rand(4, 5)
425
+ z = rng.rand(4, 5)
426
+ res1 = bootstrap((x, y, z), statistic, vectorized=True,
427
+ axis=axis, n_resamples=100, method=method, rng=0)
428
+ res2 = bootstrap((x, y, z), statistic_1d, vectorized=False,
429
+ axis=axis, n_resamples=100, method=method, rng=0)
430
+ assert_allclose(res1.confidence_interval, res2.confidence_interval)
431
+ assert_allclose(res1.standard_error, res2.standard_error)
432
+
433
+
434
+ @pytest.mark.xfail_on_32bit("Failure is not concerning; see gh-14107")
435
+ @pytest.mark.parametrize("method", ["basic", "percentile", "BCa"])
436
+ @pytest.mark.parametrize("axis", [0, 1])
437
+ def test_bootstrap_vectorized_1samp(method, axis):
438
+ def statistic(x, axis=0):
439
+ # an arbitrary, vectorized statistic
440
+ return x.mean(axis=axis)
441
+
442
+ def statistic_1d(x):
443
+ # the same statistic, not vectorized
444
+ assert x.ndim == 1
445
+ return statistic(x, axis=0)
446
+
447
+ rng = np.random.RandomState(0)
448
+ x = rng.rand(4, 5)
449
+ res1 = bootstrap((x,), statistic, vectorized=True, axis=axis,
450
+ n_resamples=100, batch=None, method=method,
451
+ rng=0)
452
+ res2 = bootstrap((x,), statistic_1d, vectorized=False, axis=axis,
453
+ n_resamples=100, batch=10, method=method,
454
+ rng=0)
455
+ assert_allclose(res1.confidence_interval, res2.confidence_interval)
456
+ assert_allclose(res1.standard_error, res2.standard_error)
457
+
458
+
459
+ @pytest.mark.parametrize("method", ["basic", "percentile", "BCa"])
460
+ def test_bootstrap_degenerate(method):
461
+ data = 35 * [10000.]
462
+ if method == "BCa":
463
+ with np.errstate(invalid='ignore'):
464
+ msg = "The BCa confidence interval cannot be calculated"
465
+ with pytest.warns(stats.DegenerateDataWarning, match=msg):
466
+ res = bootstrap([data, ], np.mean, method=method)
467
+ assert_equal(res.confidence_interval, (np.nan, np.nan))
468
+ else:
469
+ res = bootstrap([data, ], np.mean, method=method)
470
+ assert_equal(res.confidence_interval, (10000., 10000.))
471
+ assert_equal(res.standard_error, 0)
472
+
473
+
474
+ @pytest.mark.parametrize("method", ["basic", "percentile", "BCa"])
475
+ def test_bootstrap_gh15678(method):
476
+ # Check that gh-15678 is fixed: when statistic function returned a Python
477
+ # float, method="BCa" failed when trying to add a dimension to the float
478
+ rng = np.random.default_rng(354645618886684)
479
+ dist = stats.norm(loc=2, scale=4)
480
+ data = dist.rvs(size=100, random_state=rng)
481
+ data = (data,)
482
+ res = bootstrap(data, stats.skew, method=method, n_resamples=100,
483
+ rng=np.random.default_rng(9563))
484
+ # this always worked because np.apply_along_axis returns NumPy data type
485
+ ref = bootstrap(data, stats.skew, method=method, n_resamples=100,
486
+ rng=np.random.default_rng(9563), vectorized=False)
487
+ assert_allclose(res.confidence_interval, ref.confidence_interval)
488
+ assert_allclose(res.standard_error, ref.standard_error)
489
+ assert isinstance(res.standard_error, np.float64)
490
+
491
+
492
+ def test_bootstrap_min():
493
+ # Check that gh-15883 is fixed: percentileofscore should
494
+ # behave according to the 'mean' behavior and not trigger nan for BCa
495
+ rng = np.random.default_rng(1891289180021102)
496
+ dist = stats.norm(loc=2, scale=4)
497
+ data = dist.rvs(size=100, random_state=rng)
498
+ true_min = np.min(data)
499
+ data = (data,)
500
+ res = bootstrap(data, np.min, method="BCa", n_resamples=100,
501
+ rng=np.random.default_rng(3942))
502
+ assert true_min == res.confidence_interval.low
503
+ res2 = bootstrap(-np.array(data), np.max, method="BCa", n_resamples=100,
504
+ rng=np.random.default_rng(3942))
505
+ assert_allclose(-res.confidence_interval.low,
506
+ res2.confidence_interval.high)
507
+ assert_allclose(-res.confidence_interval.high,
508
+ res2.confidence_interval.low)
509
+
510
+
511
+ @pytest.mark.parametrize("additional_resamples", [0, 1000])
512
+ def test_re_bootstrap(additional_resamples):
513
+ # Test behavior of parameter `bootstrap_result`
514
+ rng = np.random.default_rng(8958153316228384)
515
+ x = rng.random(size=100)
516
+
517
+ n1 = 1000
518
+ n2 = additional_resamples
519
+ n3 = n1 + additional_resamples
520
+
521
+ rng = np.random.default_rng(296689032789913033)
522
+ res = stats.bootstrap((x,), np.mean, n_resamples=n1, rng=rng,
523
+ confidence_level=0.95, method='percentile')
524
+ res = stats.bootstrap((x,), np.mean, n_resamples=n2, rng=rng,
525
+ confidence_level=0.90, method='BCa',
526
+ bootstrap_result=res)
527
+
528
+ rng = np.random.default_rng(296689032789913033)
529
+ ref = stats.bootstrap((x,), np.mean, n_resamples=n3, rng=rng,
530
+ confidence_level=0.90, method='BCa')
531
+
532
+ assert_allclose(res.standard_error, ref.standard_error, rtol=1e-14)
533
+ assert_allclose(res.confidence_interval, ref.confidence_interval,
534
+ rtol=1e-14)
535
+
536
+
537
+ @pytest.mark.xfail_on_32bit("Sensible to machine precision")
538
+ @pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
539
+ def test_bootstrap_alternative(method):
540
+ rng = np.random.default_rng(5894822712842015040)
541
+ dist = stats.norm(loc=2, scale=4)
542
+ data = (dist.rvs(size=(100), random_state=rng),)
543
+
544
+ config = dict(data=data, statistic=np.std, rng=rng, axis=-1)
545
+ t = stats.bootstrap(**config, confidence_level=0.9)
546
+
547
+ config.update(dict(n_resamples=0, bootstrap_result=t))
548
+ l = stats.bootstrap(**config, confidence_level=0.95, alternative='less')
549
+ g = stats.bootstrap(**config, confidence_level=0.95, alternative='greater')
550
+
551
+ assert_allclose(l.confidence_interval.high, t.confidence_interval.high,
552
+ rtol=1e-14)
553
+ assert_allclose(g.confidence_interval.low, t.confidence_interval.low,
554
+ rtol=1e-14)
555
+ assert np.isneginf(l.confidence_interval.low)
556
+ assert np.isposinf(g.confidence_interval.high)
557
+
558
+ with pytest.raises(ValueError, match='`alternative` must be one of'):
559
+ stats.bootstrap(**config, alternative='ekki-ekki')
560
+
561
+
562
+ def test_jackknife_resample():
563
+ shape = 3, 4, 5, 6
564
+ np.random.seed(0)
565
+ x = np.random.rand(*shape)
566
+ y = next(_resampling._jackknife_resample(x))
567
+
568
+ for i in range(shape[-1]):
569
+ # each resample is indexed along second to last axis
570
+ # (last axis is the one the statistic will be taken over / consumed)
571
+ slc = y[..., i, :]
572
+ expected = np.delete(x, i, axis=-1)
573
+
574
+ assert np.array_equal(slc, expected)
575
+
576
+ y2 = np.concatenate(list(_resampling._jackknife_resample(x, batch=2)),
577
+ axis=-2)
578
+ assert np.array_equal(y2, y)
579
+
580
+
581
+ @pytest.mark.parametrize("rng_name", ["RandomState", "default_rng"])
582
+ def test_bootstrap_resample(rng_name):
583
+ rng = getattr(np.random, rng_name, None)
584
+ if rng is None:
585
+ pytest.skip(f"{rng_name} not available.")
586
+ rng1 = rng(0)
587
+ rng2 = rng(0)
588
+
589
+ n_resamples = 10
590
+ shape = 3, 4, 5, 6
591
+
592
+ np.random.seed(0)
593
+ x = np.random.rand(*shape)
594
+ y = _resampling._bootstrap_resample(x, n_resamples, rng=rng1)
595
+
596
+ for i in range(n_resamples):
597
+ # each resample is indexed along second to last axis
598
+ # (last axis is the one the statistic will be taken over / consumed)
599
+ slc = y[..., i, :]
600
+
601
+ js = rng_integers(rng2, 0, shape[-1], shape[-1])
602
+ expected = x[..., js]
603
+
604
+ assert np.array_equal(slc, expected)
605
+
606
+
607
+ @pytest.mark.parametrize("score", [0, 0.5, 1])
608
+ @pytest.mark.parametrize("axis", [0, 1, 2])
609
+ def test_percentile_of_score(score, axis):
610
+ shape = 10, 20, 30
611
+ np.random.seed(0)
612
+ x = np.random.rand(*shape)
613
+ p = _resampling._percentile_of_score(x, score, axis=-1)
614
+
615
+ def vectorized_pos(a, score, axis):
616
+ return np.apply_along_axis(stats.percentileofscore, axis, a, score)
617
+
618
+ p2 = vectorized_pos(x, score, axis=-1)/100
619
+
620
+ assert_allclose(p, p2, 1e-15)
621
+
622
+
623
+ def test_percentile_along_axis():
624
+ # the difference between _percentile_along_axis and np.percentile is that
625
+ # np.percentile gets _all_ the qs for each axis slice, whereas
626
+ # _percentile_along_axis gets the q corresponding with each axis slice
627
+
628
+ shape = 10, 20
629
+ rng = np.random.RandomState(0)
630
+ x = rng.rand(*shape)
631
+ q = rng.rand(*shape[:-1]) * 100
632
+ y = _resampling._percentile_along_axis(x, q)
633
+
634
+ for i in range(shape[0]):
635
+ res = y[i]
636
+ expected = np.percentile(x[i], q[i], axis=-1)
637
+ assert_allclose(res, expected, 1e-15)
638
+
639
+
640
+ @pytest.mark.parametrize("axis", [0, 1, 2])
641
+ def test_vectorize_statistic(axis):
642
+ # test that _vectorize_statistic vectorizes a statistic along `axis`
643
+
644
+ def statistic(*data, axis):
645
+ # an arbitrary, vectorized statistic
646
+ return sum(sample.mean(axis) for sample in data)
647
+
648
+ def statistic_1d(*data):
649
+ # the same statistic, not vectorized
650
+ for sample in data:
651
+ assert sample.ndim == 1
652
+ return statistic(*data, axis=0)
653
+
654
+ # vectorize the non-vectorized statistic
655
+ statistic2 = _resampling._vectorize_statistic(statistic_1d)
656
+
657
+ rng = np.random.RandomState(0)
658
+ x = rng.rand(4, 5, 6)
659
+ y = rng.rand(4, 1, 6)
660
+ z = rng.rand(1, 5, 6)
661
+
662
+ res1 = statistic(x, y, z, axis=axis)
663
+ res2 = statistic2(x, y, z, axis=axis)
664
+ assert_allclose(res1, res2)
665
+
666
+
667
+ @pytest.mark.slow
668
+ @pytest.mark.parametrize("method", ["basic", "percentile", "BCa"])
669
+ def test_vector_valued_statistic(method):
670
+ # Generate 95% confidence interval around MLE of normal distribution
671
+ # parameters. Repeat 100 times, each time on sample of size 100.
672
+ # Check that confidence interval contains true parameters ~95 times.
673
+ # Confidence intervals are estimated and stochastic; a test failure
674
+ # does not necessarily indicate that something is wrong. More important
675
+ # than values of `counts` below is that the shapes of the outputs are
676
+ # correct.
677
+
678
+ rng = np.random.default_rng(2196847219)
679
+ params = 1, 0.5
680
+ sample = stats.norm.rvs(*params, size=(100, 100), random_state=rng)
681
+
682
+ def statistic(data, axis):
683
+ return np.asarray([np.mean(data, axis),
684
+ np.std(data, axis, ddof=1)])
685
+
686
+ res = bootstrap((sample,), statistic, method=method, axis=-1,
687
+ n_resamples=9999, batch=200, random_state=rng)
688
+
689
+ counts = np.sum((res.confidence_interval.low.T < params)
690
+ & (res.confidence_interval.high.T > params),
691
+ axis=0)
692
+ assert np.all(counts >= 90)
693
+ assert np.all(counts <= 100)
694
+ assert res.confidence_interval.low.shape == (2, 100)
695
+ assert res.confidence_interval.high.shape == (2, 100)
696
+ assert res.standard_error.shape == (2, 100)
697
+ assert res.bootstrap_distribution.shape == (2, 100, 9999)
698
+
699
+
700
+ @pytest.mark.slow
701
+ @pytest.mark.filterwarnings('ignore::RuntimeWarning')
702
+ def test_vector_valued_statistic_gh17715():
703
+ # gh-17715 reported a mistake introduced in the extension of BCa to
704
+ # multi-sample statistics; a `len` should have been `.shape[-1]`. Check
705
+ # that this is resolved.
706
+
707
+ rng = np.random.default_rng(141921000979291141)
708
+
709
+ def concordance(x, y, axis):
710
+ xm = x.mean(axis)
711
+ ym = y.mean(axis)
712
+ cov = ((x - xm[..., None]) * (y - ym[..., None])).mean(axis)
713
+ return (2 * cov) / (x.var(axis) + y.var(axis) + (xm - ym) ** 2)
714
+
715
+ def statistic(tp, tn, fp, fn, axis):
716
+ actual = tp + fp
717
+ expected = tp + fn
718
+ return np.nan_to_num(concordance(actual, expected, axis))
719
+
720
+ def statistic_extradim(*args, axis):
721
+ return statistic(*args, axis)[np.newaxis, ...]
722
+
723
+ data = [[4, 0, 0, 2], # (tp, tn, fp, fn)
724
+ [2, 1, 2, 1],
725
+ [0, 6, 0, 0],
726
+ [0, 6, 3, 0],
727
+ [0, 8, 1, 0]]
728
+ data = np.array(data).T
729
+
730
+ res = bootstrap(data, statistic_extradim, rng=rng, paired=True)
731
+ ref = bootstrap(data, statistic, rng=rng, paired=True)
732
+ assert_allclose(res.confidence_interval.low[0],
733
+ ref.confidence_interval.low, atol=1e-15)
734
+ assert_allclose(res.confidence_interval.high[0],
735
+ ref.confidence_interval.high, atol=1e-15)
736
+
737
+
738
+ def test_gh_20850():
739
+ rng = np.random.default_rng(2085020850)
740
+ x = rng.random((10, 2))
741
+ y = rng.random((11, 2))
742
+ def statistic(x, y, axis):
743
+ return stats.ttest_ind(x, y, axis=axis).statistic
744
+
745
+ # The shapes do *not* need to be the same along axis
746
+ stats.bootstrap((x, y), statistic)
747
+ stats.bootstrap((x.T, y.T), statistic, axis=1)
748
+ # But even when the shapes *are* the same along axis, the lengths
749
+ # along other dimensions have to be the same (or `bootstrap` warns).
750
+ message = "Array shapes are incompatible for broadcasting."
751
+ with pytest.raises(ValueError, match=message):
752
+ stats.bootstrap((x, y[:10, 0]), statistic) # this won't work after 1.16
753
+ stats.bootstrap((x, y[:10, 0:1]), statistic) # this will
754
+ stats.bootstrap((x.T, y.T[0:1, :10]), statistic, axis=1) # this will
755
+
756
+
757
+ # --- Test Monte Carlo Hypothesis Test --- #
758
+
759
+ class TestMonteCarloHypothesisTest:
760
+ atol = 2.5e-2 # for comparing p-value
761
+
762
+ def get_rvs(self, rvs_in, rs, dtype=None, xp=np):
763
+ return lambda *args, **kwds: xp.asarray(rvs_in(*args, random_state=rs, **kwds),
764
+ dtype=dtype)
765
+
766
+ def get_statistic(self, xp):
767
+ def statistic(x, axis):
768
+ m = xp.mean(x, axis=axis)
769
+ v = xp.var(x, axis=axis, correction=1)
770
+ n = x.shape[axis]
771
+ return m / (v/n)**0.5
772
+ # return stats.ttest_1samp(x, popmean=0., axis=axis).statistic)
773
+ return statistic
774
+
775
+ def test_input_validation(self, xp):
776
+ # test that the appropriate error messages are raised for invalid input
777
+
778
+ data = xp.asarray([1., 2., 3.])
779
+ def stat(x, axis=None):
780
+ return xp.mean(x, axis=axis)
781
+
782
+ message = "Array shapes are incompatible for broadcasting."
783
+ temp = (xp.zeros((2, 5)), xp.zeros((3, 5)))
784
+ rvs = (stats.norm.rvs, stats.norm.rvs)
785
+ with pytest.raises(ValueError, match=message):
786
+ monte_carlo_test(temp, rvs, lambda x, y, axis: 1, axis=-1)
787
+
788
+ message = "`axis` must be an integer."
789
+ with pytest.raises(ValueError, match=message):
790
+ monte_carlo_test(data, stats.norm.rvs, stat, axis=1.5)
791
+
792
+ message = "`vectorized` must be `True`, `False`, or `None`."
793
+ with pytest.raises(ValueError, match=message):
794
+ monte_carlo_test(data, stats.norm.rvs, stat, vectorized=1.5)
795
+
796
+ message = "`rvs` must be callable or sequence of callables."
797
+ with pytest.raises(TypeError, match=message):
798
+ monte_carlo_test(data, None, stat)
799
+ with pytest.raises(TypeError, match=message):
800
+ temp = xp.asarray([[1., 2.], [3., 4.]])
801
+ monte_carlo_test(temp, [lambda x: x, None], stat)
802
+
803
+ message = "If `rvs` is a sequence..."
804
+ with pytest.raises(ValueError, match=message):
805
+ temp = xp.asarray([[1., 2., 3.]])
806
+ monte_carlo_test(temp, [lambda x: x, lambda x: x], stat)
807
+
808
+ message = "`statistic` must be callable."
809
+ with pytest.raises(TypeError, match=message):
810
+ monte_carlo_test(data, stats.norm.rvs, None)
811
+
812
+ message = "`n_resamples` must be a positive integer."
813
+ with pytest.raises(ValueError, match=message):
814
+ monte_carlo_test(data, stats.norm.rvs, stat, n_resamples=-1000)
815
+
816
+ message = "`n_resamples` must be a positive integer."
817
+ with pytest.raises(ValueError, match=message):
818
+ monte_carlo_test(data, stats.norm.rvs, stat, n_resamples=1000.5)
819
+
820
+ message = "`batch` must be a positive integer or None."
821
+ with pytest.raises(ValueError, match=message):
822
+ monte_carlo_test(data, stats.norm.rvs, stat, batch=-1000)
823
+
824
+ message = "`batch` must be a positive integer or None."
825
+ with pytest.raises(ValueError, match=message):
826
+ monte_carlo_test(data, stats.norm.rvs, stat, batch=1000.5)
827
+
828
+ message = "`alternative` must be in..."
829
+ with pytest.raises(ValueError, match=message):
830
+ monte_carlo_test(data, stats.norm.rvs, stat, alternative='ekki')
831
+
832
+ # *If* this raises a value error, make sure it has the intended message
833
+ message = "Signature inspection of statistic"
834
+ def rvs(size):
835
+ return xp.asarray(stats.norm.rvs(size=size))
836
+ try:
837
+ monte_carlo_test(data, rvs, xp.mean)
838
+ except ValueError as e:
839
+ assert str(e).startswith(message)
840
+
841
+ def test_input_validation_xp(self, xp):
842
+ def non_vectorized_statistic(x):
843
+ return xp.mean(x)
844
+
845
+ message = "`statistic` must be vectorized..."
846
+ sample = xp.asarray([1., 2., 3.])
847
+ if is_numpy(xp):
848
+ monte_carlo_test(sample, stats.norm.rvs, non_vectorized_statistic)
849
+ return
850
+
851
+ with pytest.raises(ValueError, match=message):
852
+ monte_carlo_test(sample, stats.norm.rvs, non_vectorized_statistic)
853
+ with pytest.raises(ValueError, match=message):
854
+ monte_carlo_test(sample, stats.norm.rvs, xp.mean, vectorized=False)
855
+
856
+ @pytest.mark.xslow
857
+ def test_batch(self, xp):
858
+ # make sure that the `batch` parameter is respected by checking the
859
+ # maximum batch size provided in calls to `statistic`
860
+ rng = np.random.default_rng(23492340193)
861
+ x = xp.asarray(rng.standard_normal(size=10))
862
+
863
+ def statistic(x, axis):
864
+ batch_size = 1 if x.ndim == 1 else x.shape[0]
865
+ statistic.batch_size = max(batch_size, statistic.batch_size)
866
+ statistic.counter += 1
867
+ return self.get_statistic(xp)(x, axis=axis)
868
+ statistic.counter = 0
869
+ statistic.batch_size = 0
870
+
871
+ kwds = {'sample': x, 'statistic': statistic,
872
+ 'n_resamples': 1000, 'vectorized': True}
873
+
874
+ kwds['rvs'] = self.get_rvs(stats.norm.rvs, np.random.default_rng(328423), xp=xp)
875
+ res1 = monte_carlo_test(batch=1, **kwds)
876
+ assert_equal(statistic.counter, 1001)
877
+ assert_equal(statistic.batch_size, 1)
878
+
879
+ kwds['rvs'] = self.get_rvs(stats.norm.rvs, np.random.default_rng(328423), xp=xp)
880
+ statistic.counter = 0
881
+ res2 = monte_carlo_test(batch=50, **kwds)
882
+ assert_equal(statistic.counter, 21)
883
+ assert_equal(statistic.batch_size, 50)
884
+
885
+ kwds['rvs'] = self.get_rvs(stats.norm.rvs, np.random.default_rng(328423), xp=xp)
886
+ statistic.counter = 0
887
+ res3 = monte_carlo_test(**kwds)
888
+ assert_equal(statistic.counter, 2)
889
+ assert_equal(statistic.batch_size, 1000)
890
+
891
+ xp_assert_equal(res1.pvalue, res3.pvalue)
892
+ xp_assert_equal(res2.pvalue, res3.pvalue)
893
+
894
+ @pytest.mark.parametrize('axis', range(-3, 3))
895
+ def test_axis_dtype(self, axis, xp):
896
+ # test that Nd-array samples are handled correctly for valid values
897
+ # of the `axis` parameter; also make sure non-default dtype is maintained
898
+ rng = np.random.default_rng(2389234)
899
+ size = [2, 3, 4]
900
+ size[axis] = 100
901
+
902
+ # Determine non-default dtype
903
+ dtype_default = xp.asarray(1.).dtype
904
+ dtype_str = 'float32'if ("64" in str(dtype_default)) else 'float64'
905
+ dtype_np = getattr(np, dtype_str)
906
+ dtype = getattr(xp, dtype_str)
907
+
908
+ # ttest_1samp is CPU array-API compatible, but it would be good to
909
+ # include CuPy in this test. We'll perform ttest_1samp with a
910
+ # NumPy array, but all the rest with be done with fully array-API
911
+ # compatible code.
912
+ x = rng.standard_normal(size=size, dtype=dtype_np)
913
+ expected = stats.ttest_1samp(x, popmean=0., axis=axis)
914
+
915
+ x = xp.asarray(x, dtype=dtype)
916
+ statistic = self.get_statistic(xp)
917
+ rvs = self.get_rvs(stats.norm.rvs, rng, dtype=dtype, xp=xp)
918
+
919
+ res = monte_carlo_test(x, rvs, statistic, vectorized=True,
920
+ n_resamples=20000, axis=axis)
921
+
922
+ ref_statistic = xp.asarray(expected.statistic, dtype=dtype)
923
+ ref_pvalue = xp.asarray(expected.pvalue, dtype=dtype)
924
+ xp_assert_close(res.statistic, ref_statistic)
925
+ xp_assert_close(res.pvalue, ref_pvalue, atol=self.atol)
926
+
927
+ @pytest.mark.parametrize('alternative', ("two-sided", "less", "greater"))
928
+ def test_alternative(self, alternative, xp):
929
+ # test that `alternative` is working as expected
930
+ rng = np.random.default_rng(65723433)
931
+
932
+ x = rng.standard_normal(size=30)
933
+ ref = stats.ttest_1samp(x, 0., alternative=alternative)
934
+
935
+ x = xp.asarray(x)
936
+ statistic = self.get_statistic(xp)
937
+ rvs = self.get_rvs(stats.norm.rvs, rng, xp=xp)
938
+
939
+ res = monte_carlo_test(x, rvs, statistic, alternative=alternative)
940
+
941
+ xp_assert_close(res.statistic, xp.asarray(ref.statistic))
942
+ xp_assert_close(res.pvalue, xp.asarray(ref.pvalue), atol=self.atol)
943
+
944
+
945
+ # Tests below involve statistics that are not yet array-API compatible.
946
+ # They can be converted when the statistics are converted.
947
+ @pytest.mark.slow
948
+ @pytest.mark.parametrize('alternative', ("less", "greater"))
949
+ @pytest.mark.parametrize('a', np.linspace(-0.5, 0.5, 5)) # skewness
950
+ def test_against_ks_1samp(self, alternative, a):
951
+ # test that monte_carlo_test can reproduce pvalue of ks_1samp
952
+ rng = np.random.default_rng(65723433)
953
+
954
+ x = stats.skewnorm.rvs(a=a, size=30, random_state=rng)
955
+ expected = stats.ks_1samp(x, stats.norm.cdf, alternative=alternative)
956
+
957
+ def statistic1d(x):
958
+ return stats.ks_1samp(x, stats.norm.cdf, mode='asymp',
959
+ alternative=alternative).statistic
960
+
961
+ norm_rvs = self.get_rvs(stats.norm.rvs, rng)
962
+ res = monte_carlo_test(x, norm_rvs, statistic1d,
963
+ n_resamples=1000, vectorized=False,
964
+ alternative=alternative)
965
+
966
+ assert_allclose(res.statistic, expected.statistic)
967
+ if alternative == 'greater':
968
+ assert_allclose(res.pvalue, expected.pvalue, atol=self.atol)
969
+ elif alternative == 'less':
970
+ assert_allclose(1-res.pvalue, expected.pvalue, atol=self.atol)
971
+
972
+ @pytest.mark.parametrize('hypotest', (stats.skewtest, stats.kurtosistest))
973
+ @pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
974
+ @pytest.mark.parametrize('a', np.linspace(-2, 2, 5)) # skewness
975
+ def test_against_normality_tests(self, hypotest, alternative, a):
976
+ # test that monte_carlo_test can reproduce pvalue of normality tests
977
+ rng = np.random.default_rng(85723405)
978
+
979
+ x = stats.skewnorm.rvs(a=a, size=150, random_state=rng)
980
+ expected = hypotest(x, alternative=alternative)
981
+
982
+ def statistic(x, axis):
983
+ return hypotest(x, axis=axis).statistic
984
+
985
+ norm_rvs = self.get_rvs(stats.norm.rvs, rng)
986
+ res = monte_carlo_test(x, norm_rvs, statistic, vectorized=True,
987
+ alternative=alternative)
988
+
989
+ assert_allclose(res.statistic, expected.statistic)
990
+ assert_allclose(res.pvalue, expected.pvalue, atol=self.atol)
991
+
992
+ @pytest.mark.parametrize('a', np.arange(-2, 3)) # skewness parameter
993
+ def test_against_normaltest(self, a):
994
+ # test that monte_carlo_test can reproduce pvalue of normaltest
995
+ rng = np.random.default_rng(12340513)
996
+
997
+ x = stats.skewnorm.rvs(a=a, size=150, random_state=rng)
998
+ expected = stats.normaltest(x)
999
+
1000
+ def statistic(x, axis):
1001
+ return stats.normaltest(x, axis=axis).statistic
1002
+
1003
+ norm_rvs = self.get_rvs(stats.norm.rvs, rng)
1004
+ res = monte_carlo_test(x, norm_rvs, statistic, vectorized=True,
1005
+ alternative='greater')
1006
+
1007
+ assert_allclose(res.statistic, expected.statistic)
1008
+ assert_allclose(res.pvalue, expected.pvalue, atol=self.atol)
1009
+
1010
+ @pytest.mark.xslow
1011
+ @pytest.mark.parametrize('a', np.linspace(-0.5, 0.5, 5)) # skewness
1012
+ def test_against_cramervonmises(self, a):
1013
+ # test that monte_carlo_test can reproduce pvalue of cramervonmises
1014
+ rng = np.random.default_rng(234874135)
1015
+
1016
+ x = stats.skewnorm.rvs(a=a, size=30, random_state=rng)
1017
+ expected = stats.cramervonmises(x, stats.norm.cdf)
1018
+
1019
+ def statistic1d(x):
1020
+ return stats.cramervonmises(x, stats.norm.cdf).statistic
1021
+
1022
+ norm_rvs = self.get_rvs(stats.norm.rvs, rng)
1023
+ res = monte_carlo_test(x, norm_rvs, statistic1d,
1024
+ n_resamples=1000, vectorized=False,
1025
+ alternative='greater')
1026
+
1027
+ assert_allclose(res.statistic, expected.statistic)
1028
+ assert_allclose(res.pvalue, expected.pvalue, atol=self.atol)
1029
+
1030
+ @pytest.mark.slow
1031
+ @pytest.mark.parametrize('dist_name', ('norm', 'logistic'))
1032
+ @pytest.mark.parametrize('i', range(5))
1033
+ def test_against_anderson(self, dist_name, i):
1034
+ # test that monte_carlo_test can reproduce results of `anderson`. Note:
1035
+ # `anderson` does not provide a p-value; it provides a list of
1036
+ # significance levels and the associated critical value of the test
1037
+ # statistic. `i` used to index this list.
1038
+
1039
+ # find the skewness for which the sample statistic matches one of the
1040
+ # critical values provided by `stats.anderson`
1041
+
1042
+ def fun(a):
1043
+ rng = np.random.default_rng(394295467)
1044
+ x = stats.tukeylambda.rvs(a, size=100, random_state=rng)
1045
+ expected = stats.anderson(x, dist_name)
1046
+ return expected.statistic - expected.critical_values[i]
1047
+ with suppress_warnings() as sup:
1048
+ sup.filter(RuntimeWarning)
1049
+ sol = root(fun, x0=0)
1050
+ assert sol.success
1051
+
1052
+ # get the significance level (p-value) associated with that critical
1053
+ # value
1054
+ a = sol.x[0]
1055
+ rng = np.random.default_rng(394295467)
1056
+ x = stats.tukeylambda.rvs(a, size=100, random_state=rng)
1057
+ expected = stats.anderson(x, dist_name)
1058
+ expected_stat = expected.statistic
1059
+ expected_p = expected.significance_level[i]/100
1060
+
1061
+ # perform equivalent Monte Carlo test and compare results
1062
+ def statistic1d(x):
1063
+ return stats.anderson(x, dist_name).statistic
1064
+
1065
+ dist_rvs = self.get_rvs(getattr(stats, dist_name).rvs, rng)
1066
+ with suppress_warnings() as sup:
1067
+ sup.filter(RuntimeWarning)
1068
+ res = monte_carlo_test(x, dist_rvs,
1069
+ statistic1d, n_resamples=1000,
1070
+ vectorized=False, alternative='greater')
1071
+
1072
+ assert_allclose(res.statistic, expected_stat)
1073
+ assert_allclose(res.pvalue, expected_p, atol=2*self.atol)
1074
+
1075
+ def test_p_never_zero(self):
1076
+ # Use biased estimate of p-value to ensure that p-value is never zero
1077
+ # per monte_carlo_test reference [1]
1078
+ rng = np.random.default_rng(2190176673029737545)
1079
+ x = np.zeros(100)
1080
+ res = monte_carlo_test(x, rng.random, np.mean,
1081
+ vectorized=True, alternative='less')
1082
+ assert res.pvalue == 0.0001
1083
+
1084
+ def test_against_ttest_ind(self):
1085
+ # test that `monte_carlo_test` can reproduce results of `ttest_ind`.
1086
+ rng = np.random.default_rng(219017667302737545)
1087
+ data = rng.random(size=(2, 5)), rng.random(size=7) # broadcastable
1088
+ rvs = rng.normal, rng.normal
1089
+ def statistic(x, y, axis):
1090
+ return stats.ttest_ind(x, y, axis=axis).statistic
1091
+
1092
+ res = stats.monte_carlo_test(data, rvs, statistic, axis=-1)
1093
+ ref = stats.ttest_ind(data[0], [data[1]], axis=-1)
1094
+ assert_allclose(res.statistic, ref.statistic)
1095
+ assert_allclose(res.pvalue, ref.pvalue, rtol=2e-2)
1096
+
1097
+ def test_against_f_oneway(self):
1098
+ # test that `monte_carlo_test` can reproduce results of `f_oneway`.
1099
+ rng = np.random.default_rng(219017667302737545)
1100
+ data = (rng.random(size=(2, 100)), rng.random(size=(2, 101)),
1101
+ rng.random(size=(2, 102)), rng.random(size=(2, 103)))
1102
+ rvs = rng.normal, rng.normal, rng.normal, rng.normal
1103
+
1104
+ def statistic(*args, axis):
1105
+ return stats.f_oneway(*args, axis=axis).statistic
1106
+
1107
+ res = stats.monte_carlo_test(data, rvs, statistic, axis=-1,
1108
+ alternative='greater')
1109
+ ref = stats.f_oneway(*data, axis=-1)
1110
+
1111
+ assert_allclose(res.statistic, ref.statistic)
1112
+ assert_allclose(res.pvalue, ref.pvalue, atol=1e-2)
1113
+
1114
+ @pytest.mark.fail_slow(2)
1115
+ @pytest.mark.xfail_on_32bit("Statistic may not depend on sample order on 32-bit")
1116
+ def test_finite_precision_statistic(self):
1117
+ # Some statistics return numerically distinct values when the values
1118
+ # should be equal in theory. Test that `monte_carlo_test` accounts
1119
+ # for this in some way.
1120
+ rng = np.random.default_rng(2549824598234528)
1121
+ n_resamples = 9999
1122
+ def rvs(size):
1123
+ return 1. * stats.bernoulli(p=0.333).rvs(size=size, random_state=rng)
1124
+
1125
+ x = rvs(100)
1126
+ res = stats.monte_carlo_test(x, rvs, np.var, alternative='less',
1127
+ n_resamples=n_resamples)
1128
+ # show that having a tolerance matters
1129
+ c0 = np.sum(res.null_distribution <= res.statistic)
1130
+ c1 = np.sum(res.null_distribution <= res.statistic*(1+1e-15))
1131
+ assert c0 != c1
1132
+ assert res.pvalue == (c1 + 1)/(n_resamples + 1)
1133
+
1134
+
1135
+ class TestPower:
1136
+ def test_input_validation(self):
1137
+ # test that the appropriate error messages are raised for invalid input
1138
+ rng = np.random.default_rng(8519895914314711673)
1139
+
1140
+ test = stats.ttest_ind
1141
+ rvs = (rng.normal, rng.normal)
1142
+ n_observations = (10, 12)
1143
+
1144
+ message = "`vectorized` must be `True`, `False`, or `None`."
1145
+ with pytest.raises(ValueError, match=message):
1146
+ power(test, rvs, n_observations, vectorized=1.5)
1147
+
1148
+ message = "`rvs` must be callable or sequence of callables."
1149
+ with pytest.raises(TypeError, match=message):
1150
+ power(test, None, n_observations)
1151
+ with pytest.raises(TypeError, match=message):
1152
+ power(test, (rng.normal, 'ekki'), n_observations)
1153
+
1154
+ message = "If `rvs` is a sequence..."
1155
+ with pytest.raises(ValueError, match=message):
1156
+ power(test, (rng.normal,), n_observations)
1157
+ with pytest.raises(ValueError, match=message):
1158
+ power(test, rvs, (10,))
1159
+
1160
+ message = "`significance` must contain floats between 0 and 1."
1161
+ with pytest.raises(ValueError, match=message):
1162
+ power(test, rvs, n_observations, significance=2)
1163
+ with pytest.raises(ValueError, match=message):
1164
+ power(test, rvs, n_observations, significance=np.linspace(-1, 1))
1165
+
1166
+ message = "`kwargs` must be a dictionary"
1167
+ with pytest.raises(TypeError, match=message):
1168
+ power(test, rvs, n_observations, kwargs=(1, 2, 3))
1169
+
1170
+ message = "shape mismatch: objects cannot be broadcast"
1171
+ with pytest.raises(ValueError, match=message):
1172
+ power(test, rvs, ([10, 11], [12, 13, 14]))
1173
+ with pytest.raises(ValueError, match=message):
1174
+ power(test, rvs, ([10, 11], [12, 13]), kwargs={'x': [1, 2, 3]})
1175
+
1176
+ message = "`test` must be callable"
1177
+ with pytest.raises(TypeError, match=message):
1178
+ power(None, rvs, n_observations)
1179
+
1180
+ message = "`n_resamples` must be a positive integer"
1181
+ with pytest.raises(ValueError, match=message):
1182
+ power(test, rvs, n_observations, n_resamples=-10)
1183
+ with pytest.raises(ValueError, match=message):
1184
+ power(test, rvs, n_observations, n_resamples=10.5)
1185
+
1186
+ message = "`batch` must be a positive integer"
1187
+ with pytest.raises(ValueError, match=message):
1188
+ power(test, rvs, n_observations, batch=-10)
1189
+ with pytest.raises(ValueError, match=message):
1190
+ power(test, rvs, n_observations, batch=10.5)
1191
+
1192
+ @pytest.mark.slow
1193
+ def test_batch(self):
1194
+ # make sure that the `batch` parameter is respected by checking the
1195
+ # maximum batch size provided in calls to `test`
1196
+ rng = np.random.default_rng(23492340193)
1197
+
1198
+ def test(x, axis):
1199
+ batch_size = 1 if x.ndim == 1 else len(x)
1200
+ test.batch_size = max(batch_size, test.batch_size)
1201
+ test.counter += 1
1202
+ return stats.ttest_1samp(x, 0, axis=axis).pvalue
1203
+ test.counter = 0
1204
+ test.batch_size = 0
1205
+
1206
+ kwds = dict(test=test, n_observations=10, n_resamples=1000)
1207
+
1208
+ rng = np.random.default_rng(23492340193)
1209
+ res1 = power(**kwds, rvs=rng.normal, batch=1)
1210
+ assert_equal(test.counter, 1000)
1211
+ assert_equal(test.batch_size, 1)
1212
+
1213
+ rng = np.random.default_rng(23492340193)
1214
+ test.counter = 0
1215
+ res2 = power(**kwds, rvs=rng.normal, batch=50)
1216
+ assert_equal(test.counter, 20)
1217
+ assert_equal(test.batch_size, 50)
1218
+
1219
+ rng = np.random.default_rng(23492340193)
1220
+ test.counter = 0
1221
+ res3 = power(**kwds, rvs=rng.normal, batch=1000)
1222
+ assert_equal(test.counter, 1)
1223
+ assert_equal(test.batch_size, 1000)
1224
+
1225
+ assert_equal(res1.power, res3.power)
1226
+ assert_equal(res2.power, res3.power)
1227
+
1228
+ @pytest.mark.slow
1229
+ def test_vectorization(self):
1230
+ # Test that `power` is vectorized as expected
1231
+ rng = np.random.default_rng(25495254834552)
1232
+
1233
+ # Single vectorized call
1234
+ popmeans = np.array([0, 0.2])
1235
+ def test(x, alternative, axis=-1):
1236
+ # ensure that popmeans axis is zeroth and orthogonal to the rest
1237
+ popmeans_expanded = np.expand_dims(popmeans, tuple(range(1, x.ndim + 1)))
1238
+ return stats.ttest_1samp(x, popmeans_expanded, alternative=alternative,
1239
+ axis=axis)
1240
+
1241
+ # nx and kwargs broadcast against one another
1242
+ nx = np.asarray([10, 15, 20, 50, 100])[:, np.newaxis]
1243
+ kwargs = {'alternative': ['less', 'greater', 'two-sided']}
1244
+
1245
+ # This dimension is added to the beginning
1246
+ significance = np.asarray([0.01, 0.025, 0.05, 0.1])
1247
+ res = stats.power(test, rng.normal, nx, significance=significance,
1248
+ kwargs=kwargs)
1249
+
1250
+ # Looping over all combinations
1251
+ ref = []
1252
+ for significance_i in significance:
1253
+ for nx_i in nx:
1254
+ for alternative_i in kwargs['alternative']:
1255
+ for popmean_i in popmeans:
1256
+ def test2(x, axis=-1):
1257
+ return stats.ttest_1samp(x, popmean_i, axis=axis,
1258
+ alternative=alternative_i)
1259
+
1260
+ tmp = stats.power(test2, rng.normal, nx_i,
1261
+ significance=significance_i)
1262
+ ref.append(tmp.power)
1263
+ ref = np.reshape(ref, res.power.shape)
1264
+
1265
+ # Show that results are similar
1266
+ assert_allclose(res.power, ref, rtol=2e-2, atol=1e-2)
1267
+
1268
+ def test_ttest_ind_null(self):
1269
+ # Check that the p-values of `ttest_ind` are uniformly distributed under
1270
+ # the null hypothesis
1271
+ rng = np.random.default_rng(254952548345528)
1272
+
1273
+ test = stats.ttest_ind
1274
+ n_observations = rng.integers(10, 100, size=(2, 10))
1275
+ rvs = rng.normal, rng.normal
1276
+ significance = np.asarray([0.01, 0.05, 0.1])
1277
+ res = stats.power(test, rvs, n_observations, significance=significance)
1278
+ significance = np.broadcast_to(significance[:, np.newaxis], res.power.shape)
1279
+ assert_allclose(res.power, significance, atol=1e-2)
1280
+
1281
+ def test_ttest_1samp_power(self):
1282
+ # Check simulated ttest_1samp power against reference
1283
+ rng = np.random.default_rng(254952548345528)
1284
+
1285
+ # Reference values computed with statmodels
1286
+ # import numpy as np
1287
+ # from statsmodels.stats.power import tt_solve_power
1288
+ # tt_solve_power = np.vectorize(tt_solve_power)
1289
+ # tt_solve_power([0.1, 0.5, 0.9], [[10], [20]], [[[0.01]], [[0.05]]])
1290
+ ref = [[[0.0126515 , 0.10269751, 0.40415802],
1291
+ [0.01657775, 0.29734608, 0.86228288]],
1292
+ [[0.0592903 , 0.29317561, 0.71718121],
1293
+ [0.07094116, 0.56450441, 0.96815163]]]
1294
+
1295
+ kwargs = {'popmean': [0.1, 0.5, 0.9]}
1296
+ n_observations = [[10], [20]]
1297
+ significance = [0.01, 0.05]
1298
+ res = stats.power(stats.ttest_1samp, rng.normal, n_observations,
1299
+ significance=significance, kwargs=kwargs)
1300
+ assert_allclose(res.power, ref, atol=1e-2)
1301
+
1302
+
1303
+ class TestPermutationTest:
1304
+
1305
+ rtol = 1e-14
1306
+
1307
+ def setup_method(self):
1308
+ self.rng = np.random.default_rng(7170559330470561044)
1309
+
1310
+ # -- Input validation -- #
1311
+
1312
+ def test_permutation_test_iv(self):
1313
+
1314
+ def stat(x, y, axis):
1315
+ return stats.ttest_ind((x, y), axis).statistic
1316
+
1317
+ message = "each sample in `data` must contain two or more ..."
1318
+ with pytest.raises(ValueError, match=message):
1319
+ permutation_test(([1, 2, 3], [1]), stat)
1320
+
1321
+ message = "`data` must be a tuple containing at least two samples"
1322
+ with pytest.raises(ValueError, match=message):
1323
+ permutation_test((1,), stat)
1324
+ with pytest.raises(TypeError, match=message):
1325
+ permutation_test(1, stat)
1326
+
1327
+ message = "`axis` must be an integer."
1328
+ with pytest.raises(ValueError, match=message):
1329
+ permutation_test(([1, 2, 3], [1, 2, 3]), stat, axis=1.5)
1330
+
1331
+ message = "`permutation_type` must be in..."
1332
+ with pytest.raises(ValueError, match=message):
1333
+ permutation_test(([1, 2, 3], [1, 2, 3]), stat,
1334
+ permutation_type="ekki")
1335
+
1336
+ message = "`vectorized` must be `True`, `False`, or `None`."
1337
+ with pytest.raises(ValueError, match=message):
1338
+ permutation_test(([1, 2, 3], [1, 2, 3]), stat, vectorized=1.5)
1339
+
1340
+ message = "`n_resamples` must be a positive integer."
1341
+ with pytest.raises(ValueError, match=message):
1342
+ permutation_test(([1, 2, 3], [1, 2, 3]), stat, n_resamples=-1000)
1343
+
1344
+ message = "`n_resamples` must be a positive integer."
1345
+ with pytest.raises(ValueError, match=message):
1346
+ permutation_test(([1, 2, 3], [1, 2, 3]), stat, n_resamples=1000.5)
1347
+
1348
+ message = "`batch` must be a positive integer or None."
1349
+ with pytest.raises(ValueError, match=message):
1350
+ permutation_test(([1, 2, 3], [1, 2, 3]), stat, batch=-1000)
1351
+
1352
+ message = "`batch` must be a positive integer or None."
1353
+ with pytest.raises(ValueError, match=message):
1354
+ permutation_test(([1, 2, 3], [1, 2, 3]), stat, batch=1000.5)
1355
+
1356
+ message = "`alternative` must be in..."
1357
+ with pytest.raises(ValueError, match=message):
1358
+ permutation_test(([1, 2, 3], [1, 2, 3]), stat, alternative='ekki')
1359
+
1360
+ message = "SeedSequence expects int or sequence of ints"
1361
+ with pytest.raises(TypeError, match=message):
1362
+ permutation_test(([1, 2, 3], [1, 2, 3]), stat, rng='herring')
1363
+
1364
+ # -- Test Parameters -- #
1365
+ # SPEC-007 leave one call with seed to check it still works
1366
+ @pytest.mark.parametrize('random_state', [np.random.RandomState,
1367
+ np.random.default_rng])
1368
+ @pytest.mark.parametrize('permutation_type',
1369
+ ['pairings', 'samples', 'independent'])
1370
+ def test_batch(self, permutation_type, random_state):
1371
+ # make sure that the `batch` parameter is respected by checking the
1372
+ # maximum batch size provided in calls to `statistic`
1373
+ x = self.rng.random(10)
1374
+ y = self.rng.random(10)
1375
+
1376
+ def statistic(x, y, axis):
1377
+ batch_size = 1 if x.ndim == 1 else len(x)
1378
+ statistic.batch_size = max(batch_size, statistic.batch_size)
1379
+ statistic.counter += 1
1380
+ return np.mean(x, axis=axis) - np.mean(y, axis=axis)
1381
+ statistic.counter = 0
1382
+ statistic.batch_size = 0
1383
+
1384
+ kwds = {'n_resamples': 1000, 'permutation_type': permutation_type,
1385
+ 'vectorized': True}
1386
+ res1 = stats.permutation_test((x, y), statistic, batch=1,
1387
+ random_state=random_state(0), **kwds)
1388
+ assert_equal(statistic.counter, 1001)
1389
+ assert_equal(statistic.batch_size, 1)
1390
+
1391
+ statistic.counter = 0
1392
+ res2 = stats.permutation_test((x, y), statistic, batch=50,
1393
+ random_state=random_state(0), **kwds)
1394
+ assert_equal(statistic.counter, 21)
1395
+ assert_equal(statistic.batch_size, 50)
1396
+
1397
+ statistic.counter = 0
1398
+ res3 = stats.permutation_test((x, y), statistic, batch=1000,
1399
+ random_state=random_state(0), **kwds)
1400
+ assert_equal(statistic.counter, 2)
1401
+ assert_equal(statistic.batch_size, 1000)
1402
+
1403
+ assert_equal(res1.pvalue, res3.pvalue)
1404
+ assert_equal(res2.pvalue, res3.pvalue)
1405
+
1406
+ # SPEC-007 leave at least one call with seed to check it still works
1407
+ @pytest.mark.parametrize('random_state', [np.random.RandomState,
1408
+ np.random.default_rng])
1409
+ @pytest.mark.parametrize('permutation_type, exact_size',
1410
+ [('pairings', special.factorial(3)**2),
1411
+ ('samples', 2**3),
1412
+ ('independent', special.binom(6, 3))])
1413
+ def test_permutations(self, permutation_type, exact_size, random_state):
1414
+ # make sure that the `permutations` parameter is respected by checking
1415
+ # the size of the null distribution
1416
+ x = self.rng.random(3)
1417
+ y = self.rng.random(3)
1418
+
1419
+ def statistic(x, y, axis):
1420
+ return np.mean(x, axis=axis) - np.mean(y, axis=axis)
1421
+
1422
+ kwds = {'permutation_type': permutation_type,
1423
+ 'vectorized': True}
1424
+ res = stats.permutation_test((x, y), statistic, n_resamples=3,
1425
+ random_state=random_state(0), **kwds)
1426
+ assert_equal(res.null_distribution.size, 3)
1427
+
1428
+ res = stats.permutation_test((x, y), statistic, **kwds)
1429
+ assert_equal(res.null_distribution.size, exact_size)
1430
+
1431
+ # -- Randomized Permutation Tests -- #
1432
+
1433
+ # To get reasonable accuracy, these next three tests are somewhat slow.
1434
+ # Originally, I had them passing for all combinations of permutation type,
1435
+ # alternative, and RNG, but that takes too long for CI. Instead, split
1436
+ # into three tests, each testing a particular combination of the three
1437
+ # parameters.
1438
+
1439
+ def test_randomized_test_against_exact_both(self):
1440
+ # check that the randomized and exact tests agree to reasonable
1441
+ # precision for permutation_type='both
1442
+
1443
+ alternative, rng = 'less', 0
1444
+
1445
+ nx, ny, permutations = 8, 9, 24000
1446
+ assert special.binom(nx + ny, nx) > permutations
1447
+
1448
+ x = stats.norm.rvs(size=nx)
1449
+ y = stats.norm.rvs(size=ny)
1450
+ data = x, y
1451
+
1452
+ def statistic(x, y, axis):
1453
+ return np.mean(x, axis=axis) - np.mean(y, axis=axis)
1454
+
1455
+ kwds = {'vectorized': True, 'permutation_type': 'independent',
1456
+ 'batch': 100, 'alternative': alternative, 'rng': rng}
1457
+ res = permutation_test(data, statistic, n_resamples=permutations,
1458
+ **kwds)
1459
+ res2 = permutation_test(data, statistic, n_resamples=np.inf, **kwds)
1460
+
1461
+ assert res.statistic == res2.statistic
1462
+ assert_allclose(res.pvalue, res2.pvalue, atol=1e-2)
1463
+
1464
+ @pytest.mark.slow()
1465
+ def test_randomized_test_against_exact_samples(self):
1466
+ # check that the randomized and exact tests agree to reasonable
1467
+ # precision for permutation_type='samples'
1468
+
1469
+ alternative, rng = 'greater', None
1470
+
1471
+ nx, ny, permutations = 15, 15, 32000
1472
+ assert 2**nx > permutations
1473
+
1474
+ x = stats.norm.rvs(size=nx)
1475
+ y = stats.norm.rvs(size=ny)
1476
+ data = x, y
1477
+
1478
+ def statistic(x, y, axis):
1479
+ return np.mean(x - y, axis=axis)
1480
+
1481
+ kwds = {'vectorized': True, 'permutation_type': 'samples',
1482
+ 'batch': 100, 'alternative': alternative, 'rng': rng}
1483
+ res = permutation_test(data, statistic, n_resamples=permutations,
1484
+ **kwds)
1485
+ res2 = permutation_test(data, statistic, n_resamples=np.inf, **kwds)
1486
+
1487
+ assert res.statistic == res2.statistic
1488
+ assert_allclose(res.pvalue, res2.pvalue, atol=1e-2)
1489
+
1490
+ def test_randomized_test_against_exact_pairings(self):
1491
+ # check that the randomized and exact tests agree to reasonable
1492
+ # precision for permutation_type='pairings'
1493
+
1494
+ alternative, rng = 'two-sided', self.rng
1495
+
1496
+ nx, ny, permutations = 8, 8, 40000
1497
+ assert special.factorial(nx) > permutations
1498
+
1499
+ x = stats.norm.rvs(size=nx)
1500
+ y = stats.norm.rvs(size=ny)
1501
+ data = [x]
1502
+
1503
+ def statistic1d(x):
1504
+ return stats.pearsonr(x, y)[0]
1505
+
1506
+ statistic = _resampling._vectorize_statistic(statistic1d)
1507
+
1508
+ kwds = {'vectorized': True, 'permutation_type': 'samples',
1509
+ 'batch': 100, 'alternative': alternative, 'rng': rng}
1510
+ res = permutation_test(data, statistic, n_resamples=permutations,
1511
+ **kwds)
1512
+ res2 = permutation_test(data, statistic, n_resamples=np.inf, **kwds)
1513
+
1514
+ assert res.statistic == res2.statistic
1515
+ assert_allclose(res.pvalue, res2.pvalue, atol=1e-2)
1516
+
1517
+ # -- Independent (Unpaired) Sample Tests -- #
1518
+
1519
+ @pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
1520
+ def test_against_ks_2samp(self, alternative):
1521
+
1522
+ x = self.rng.normal(size=4, scale=1)
1523
+ y = self.rng.normal(size=5, loc=3, scale=3)
1524
+
1525
+ expected = stats.ks_2samp(x, y, alternative=alternative, mode='exact')
1526
+
1527
+ def statistic1d(x, y):
1528
+ return stats.ks_2samp(x, y, mode='asymp',
1529
+ alternative=alternative).statistic
1530
+
1531
+ # ks_2samp is always a one-tailed 'greater' test
1532
+ # it's the statistic that changes (D+ vs D- vs max(D+, D-))
1533
+ res = permutation_test((x, y), statistic1d, n_resamples=np.inf,
1534
+ alternative='greater', rng=self.rng)
1535
+
1536
+ assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
1537
+ assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
1538
+
1539
+ @pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
1540
+ def test_against_ansari(self, alternative):
1541
+
1542
+ x = self.rng.normal(size=4, scale=1)
1543
+ y = self.rng.normal(size=5, scale=3)
1544
+
1545
+ # ansari has a different convention for 'alternative'
1546
+ alternative_correspondence = {"less": "greater",
1547
+ "greater": "less",
1548
+ "two-sided": "two-sided"}
1549
+ alternative_scipy = alternative_correspondence[alternative]
1550
+ expected = stats.ansari(x, y, alternative=alternative_scipy)
1551
+
1552
+ def statistic1d(x, y):
1553
+ return stats.ansari(x, y).statistic
1554
+
1555
+ res = permutation_test((x, y), statistic1d, n_resamples=np.inf,
1556
+ alternative=alternative, rng=self.rng)
1557
+
1558
+ assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
1559
+ assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
1560
+
1561
+ @pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
1562
+ def test_against_mannwhitneyu(self, alternative):
1563
+
1564
+ x = stats.uniform.rvs(size=(3, 5, 2), loc=0, random_state=self.rng)
1565
+ y = stats.uniform.rvs(size=(3, 5, 2), loc=0.05, random_state=self.rng)
1566
+
1567
+ expected = stats.mannwhitneyu(x, y, axis=1, alternative=alternative)
1568
+
1569
+ def statistic(x, y, axis):
1570
+ return stats.mannwhitneyu(x, y, axis=axis).statistic
1571
+
1572
+ res = permutation_test((x, y), statistic, vectorized=True,
1573
+ n_resamples=np.inf, alternative=alternative,
1574
+ axis=1, rng=self.rng)
1575
+
1576
+ assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
1577
+ assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
1578
+
1579
+ def test_against_cvm(self):
1580
+
1581
+ x = stats.norm.rvs(size=4, scale=1, random_state=self.rng)
1582
+ y = stats.norm.rvs(size=5, loc=3, scale=3, random_state=self.rng)
1583
+
1584
+ expected = stats.cramervonmises_2samp(x, y, method='exact')
1585
+
1586
+ def statistic1d(x, y):
1587
+ return stats.cramervonmises_2samp(x, y,
1588
+ method='asymptotic').statistic
1589
+
1590
+ # cramervonmises_2samp has only one alternative, greater
1591
+ res = permutation_test((x, y), statistic1d, n_resamples=np.inf,
1592
+ alternative='greater', rng=self.rng)
1593
+
1594
+ assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
1595
+ assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
1596
+
1597
+ @pytest.mark.xslow()
1598
+ @pytest.mark.parametrize('axis', (-1, 2))
1599
+ def test_vectorized_nsamp_ptype_both(self, axis):
1600
+ # Test that permutation_test with permutation_type='independent' works
1601
+ # properly for a 3-sample statistic with nd array samples of different
1602
+ # (but compatible) shapes and ndims. Show that exact permutation test
1603
+ # and random permutation tests approximate SciPy's asymptotic pvalues
1604
+ # and that exact and random permutation test results are even closer
1605
+ # to one another (than they are to the asymptotic results).
1606
+
1607
+ # Three samples, different (but compatible) shapes with different ndims
1608
+ rng = np.random.default_rng(6709265303529651545)
1609
+ x = rng.random(size=(3))
1610
+ y = rng.random(size=(1, 3, 2))
1611
+ z = rng.random(size=(2, 1, 4))
1612
+ data = (x, y, z)
1613
+
1614
+ # Define the statistic (and pvalue for comparison)
1615
+ def statistic1d(*data):
1616
+ return stats.kruskal(*data).statistic
1617
+
1618
+ def pvalue1d(*data):
1619
+ return stats.kruskal(*data).pvalue
1620
+
1621
+ statistic = _resampling._vectorize_statistic(statistic1d)
1622
+ pvalue = _resampling._vectorize_statistic(pvalue1d)
1623
+
1624
+ # Calculate the expected results
1625
+ x2 = np.broadcast_to(x, (2, 3, 3)) # broadcast manually because
1626
+ y2 = np.broadcast_to(y, (2, 3, 2)) # _vectorize_statistic doesn't
1627
+ z2 = np.broadcast_to(z, (2, 3, 4))
1628
+ expected_statistic = statistic(x2, y2, z2, axis=axis)
1629
+ expected_pvalue = pvalue(x2, y2, z2, axis=axis)
1630
+
1631
+ # Calculate exact and randomized permutation results
1632
+ kwds = {'vectorized': False, 'axis': axis, 'alternative': 'greater',
1633
+ 'permutation_type': 'independent', 'rng': self.rng}
1634
+ res = permutation_test(data, statistic1d, n_resamples=np.inf, **kwds)
1635
+ res2 = permutation_test(data, statistic1d, n_resamples=1000, **kwds)
1636
+
1637
+ # Check results
1638
+ assert_allclose(res.statistic, expected_statistic, rtol=self.rtol)
1639
+ assert_allclose(res.statistic, res2.statistic, rtol=self.rtol)
1640
+ assert_allclose(res.pvalue, expected_pvalue, atol=6e-2)
1641
+ assert_allclose(res.pvalue, res2.pvalue, atol=3e-2)
1642
+
1643
+ # -- Paired-Sample Tests -- #
1644
+
1645
+ @pytest.mark.slow
1646
+ @pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
1647
+ def test_against_wilcoxon(self, alternative):
1648
+
1649
+ x = stats.uniform.rvs(size=(3, 6, 2), loc=0, random_state=self.rng)
1650
+ y = stats.uniform.rvs(size=(3, 6, 2), loc=0.05, random_state=self.rng)
1651
+
1652
+ # We'll check both 1- and 2-sample versions of the same test;
1653
+ # we expect identical results to wilcoxon in all cases.
1654
+ def statistic_1samp_1d(z):
1655
+ # 'less' ensures we get the same of two statistics every time
1656
+ return stats.wilcoxon(z, alternative='less').statistic
1657
+
1658
+ def statistic_2samp_1d(x, y):
1659
+ return stats.wilcoxon(x, y, alternative='less').statistic
1660
+
1661
+ def test_1d(x, y):
1662
+ return stats.wilcoxon(x, y, alternative=alternative)
1663
+
1664
+ test = _resampling._vectorize_statistic(test_1d)
1665
+
1666
+ expected = test(x, y, axis=1)
1667
+ expected_stat = expected[0]
1668
+ expected_p = expected[1]
1669
+
1670
+ kwds = {'vectorized': False, 'axis': 1, 'alternative': alternative,
1671
+ 'permutation_type': 'samples', 'rng': self.rng,
1672
+ 'n_resamples': np.inf}
1673
+ res1 = permutation_test((x-y,), statistic_1samp_1d, **kwds)
1674
+ res2 = permutation_test((x, y), statistic_2samp_1d, **kwds)
1675
+
1676
+ # `wilcoxon` returns a different statistic with 'two-sided'
1677
+ assert_allclose(res1.statistic, res2.statistic, rtol=self.rtol)
1678
+ if alternative != 'two-sided':
1679
+ assert_allclose(res2.statistic, expected_stat, rtol=self.rtol)
1680
+
1681
+ assert_allclose(res2.pvalue, expected_p, rtol=self.rtol)
1682
+ assert_allclose(res1.pvalue, res2.pvalue, rtol=self.rtol)
1683
+
1684
+ @pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
1685
+ def test_against_binomtest(self, alternative):
1686
+
1687
+ x = self.rng.integers(0, 2, size=10)
1688
+ x[x == 0] = -1
1689
+ # More naturally, the test would flip elements between 0 and one.
1690
+ # However, permutation_test will flip the _signs_ of the elements.
1691
+ # So we have to work with +1/-1 instead of 1/0.
1692
+
1693
+ def statistic(x, axis=0):
1694
+ return np.sum(x > 0, axis=axis)
1695
+
1696
+ k, n, p = statistic(x), 10, 0.5
1697
+ expected = stats.binomtest(k, n, p, alternative=alternative)
1698
+
1699
+ res = stats.permutation_test((x,), statistic, vectorized=True,
1700
+ permutation_type='samples',
1701
+ n_resamples=np.inf, rng=self.rng,
1702
+ alternative=alternative)
1703
+ assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
1704
+
1705
+ # -- Exact Association Tests -- #
1706
+
1707
+ def test_against_kendalltau(self):
1708
+
1709
+ x = self.rng.normal(size=6)
1710
+ y = x + self.rng.normal(size=6)
1711
+
1712
+ expected = stats.kendalltau(x, y, method='exact')
1713
+
1714
+ def statistic1d(x):
1715
+ return stats.kendalltau(x, y, method='asymptotic').statistic
1716
+
1717
+ # kendalltau currently has only one alternative, two-sided
1718
+ res = permutation_test((x,), statistic1d, permutation_type='pairings',
1719
+ n_resamples=np.inf, rng=self.rng)
1720
+
1721
+ assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
1722
+ assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
1723
+
1724
+ @pytest.mark.parametrize('alternative', ('less', 'greater', 'two-sided'))
1725
+ def test_against_fisher_exact(self, alternative):
1726
+
1727
+ def statistic(x,):
1728
+ return np.sum((x == 1) & (y == 1))
1729
+
1730
+ # x and y are binary random variables with some dependence
1731
+ rng = np.random.default_rng(6235696159000529929)
1732
+ x = (rng.random(7) > 0.6).astype(float)
1733
+ y = (rng.random(7) + 0.25*x > 0.6).astype(float)
1734
+ tab = stats.contingency.crosstab(x, y)[1]
1735
+
1736
+ res = permutation_test((x,), statistic, permutation_type='pairings',
1737
+ n_resamples=np.inf, alternative=alternative,
1738
+ rng=rng)
1739
+ res2 = stats.fisher_exact(tab, alternative=alternative)
1740
+
1741
+ assert_allclose(res.pvalue, res2[1])
1742
+
1743
+ @pytest.mark.xslow()
1744
+ @pytest.mark.parametrize('axis', (-2, 1))
1745
+ def test_vectorized_nsamp_ptype_samples(self, axis):
1746
+ # Test that permutation_test with permutation_type='samples' works
1747
+ # properly for a 3-sample statistic with nd array samples of different
1748
+ # (but compatible) shapes and ndims. Show that exact permutation test
1749
+ # reproduces SciPy's exact pvalue and that random permutation test
1750
+ # approximates it.
1751
+
1752
+ x = self.rng.random(size=(2, 4, 3))
1753
+ y = self.rng.random(size=(1, 4, 3))
1754
+ z = self.rng.random(size=(2, 4, 1))
1755
+ x = stats.rankdata(x, axis=axis)
1756
+ y = stats.rankdata(y, axis=axis)
1757
+ z = stats.rankdata(z, axis=axis)
1758
+ y = y[0] # to check broadcast with different ndim
1759
+ data = (x, y, z)
1760
+
1761
+ def statistic1d(*data):
1762
+ return stats.page_trend_test(data, ranked=True,
1763
+ method='asymptotic').statistic
1764
+
1765
+ def pvalue1d(*data):
1766
+ return stats.page_trend_test(data, ranked=True,
1767
+ method='exact').pvalue
1768
+
1769
+ statistic = _resampling._vectorize_statistic(statistic1d)
1770
+ pvalue = _resampling._vectorize_statistic(pvalue1d)
1771
+
1772
+ expected_statistic = statistic(*np.broadcast_arrays(*data), axis=axis)
1773
+ expected_pvalue = pvalue(*np.broadcast_arrays(*data), axis=axis)
1774
+
1775
+ # Let's forgive this use of an integer seed, please.
1776
+ kwds = {'vectorized': False, 'axis': axis, 'alternative': 'greater',
1777
+ 'permutation_type': 'pairings', 'rng': 0}
1778
+ res = permutation_test(data, statistic1d, n_resamples=np.inf, **kwds)
1779
+ res2 = permutation_test(data, statistic1d, n_resamples=5000, **kwds)
1780
+
1781
+ assert_allclose(res.statistic, expected_statistic, rtol=self.rtol)
1782
+ assert_allclose(res.statistic, res2.statistic, rtol=self.rtol)
1783
+ assert_allclose(res.pvalue, expected_pvalue, rtol=self.rtol)
1784
+ assert_allclose(res.pvalue, res2.pvalue, atol=3e-2)
1785
+
1786
+ # -- Test Against External References -- #
1787
+
1788
+ tie_case_1 = {'x': [1, 2, 3, 4], 'y': [1.5, 2, 2.5],
1789
+ 'expected_less': 0.2000000000,
1790
+ 'expected_2sided': 0.4, # 2*expected_less
1791
+ 'expected_Pr_gte_S_mean': 0.3428571429, # see note below
1792
+ 'expected_statistic': 7.5,
1793
+ 'expected_avg': 9.142857, 'expected_std': 1.40698}
1794
+ tie_case_2 = {'x': [111, 107, 100, 99, 102, 106, 109, 108],
1795
+ 'y': [107, 108, 106, 98, 105, 103, 110, 105, 104],
1796
+ 'expected_less': 0.1555738379,
1797
+ 'expected_2sided': 0.3111476758,
1798
+ 'expected_Pr_gte_S_mean': 0.2969971205, # see note below
1799
+ 'expected_statistic': 32.5,
1800
+ 'expected_avg': 38.117647, 'expected_std': 5.172124}
1801
+
1802
+ @pytest.mark.xslow() # only the second case is slow, really
1803
+ @pytest.mark.parametrize('case', (tie_case_1, tie_case_2))
1804
+ def test_with_ties(self, case):
1805
+ """
1806
+ Results above from SAS PROC NPAR1WAY, e.g.
1807
+
1808
+ DATA myData;
1809
+ INPUT X Y;
1810
+ CARDS;
1811
+ 1 1
1812
+ 1 2
1813
+ 1 3
1814
+ 1 4
1815
+ 2 1.5
1816
+ 2 2
1817
+ 2 2.5
1818
+ ods graphics on;
1819
+ proc npar1way AB data=myData;
1820
+ class X;
1821
+ EXACT;
1822
+ run;
1823
+ ods graphics off;
1824
+
1825
+ Note: SAS provides Pr >= |S-Mean|, which is different from our
1826
+ definition of a two-sided p-value.
1827
+
1828
+ """
1829
+
1830
+ x = case['x']
1831
+ y = case['y']
1832
+
1833
+ expected_statistic = case['expected_statistic']
1834
+ expected_less = case['expected_less']
1835
+ expected_2sided = case['expected_2sided']
1836
+ expected_Pr_gte_S_mean = case['expected_Pr_gte_S_mean']
1837
+ expected_avg = case['expected_avg']
1838
+ expected_std = case['expected_std']
1839
+
1840
+ def statistic1d(x, y):
1841
+ return stats.ansari(x, y).statistic
1842
+
1843
+ with np.testing.suppress_warnings() as sup:
1844
+ sup.filter(UserWarning, "Ties preclude use of exact statistic")
1845
+ res = permutation_test((x, y), statistic1d, n_resamples=np.inf,
1846
+ alternative='less')
1847
+ res2 = permutation_test((x, y), statistic1d, n_resamples=np.inf,
1848
+ alternative='two-sided')
1849
+
1850
+ assert_allclose(res.statistic, expected_statistic, rtol=self.rtol)
1851
+ assert_allclose(res.pvalue, expected_less, atol=1e-10)
1852
+ assert_allclose(res2.pvalue, expected_2sided, atol=1e-10)
1853
+ assert_allclose(res2.null_distribution.mean(), expected_avg, rtol=1e-6)
1854
+ assert_allclose(res2.null_distribution.std(), expected_std, rtol=1e-6)
1855
+
1856
+ # SAS provides Pr >= |S-Mean|; might as well check against that, too
1857
+ S = res.statistic
1858
+ mean = res.null_distribution.mean()
1859
+ n = len(res.null_distribution)
1860
+ Pr_gte_S_mean = np.sum(np.abs(res.null_distribution-mean)
1861
+ >= np.abs(S-mean))/n
1862
+ assert_allclose(expected_Pr_gte_S_mean, Pr_gte_S_mean)
1863
+
1864
+ @pytest.mark.slow
1865
+ @pytest.mark.parametrize('alternative, expected_pvalue',
1866
+ (('less', 0.9708333333333),
1867
+ ('greater', 0.05138888888889),
1868
+ ('two-sided', 0.1027777777778)))
1869
+ def test_against_spearmanr_in_R(self, alternative, expected_pvalue):
1870
+ """
1871
+ Results above from R cor.test, e.g.
1872
+
1873
+ options(digits=16)
1874
+ x <- c(1.76405235, 0.40015721, 0.97873798,
1875
+ 2.2408932, 1.86755799, -0.97727788)
1876
+ y <- c(2.71414076, 0.2488, 0.87551913,
1877
+ 2.6514917, 2.01160156, 0.47699563)
1878
+ cor.test(x, y, method = "spearm", alternative = "t")
1879
+ """
1880
+ # data comes from
1881
+ # np.random.seed(0)
1882
+ # x = stats.norm.rvs(size=6)
1883
+ # y = x + stats.norm.rvs(size=6)
1884
+ x = [1.76405235, 0.40015721, 0.97873798,
1885
+ 2.2408932, 1.86755799, -0.97727788]
1886
+ y = [2.71414076, 0.2488, 0.87551913,
1887
+ 2.6514917, 2.01160156, 0.47699563]
1888
+ expected_statistic = 0.7714285714285715
1889
+
1890
+ def statistic1d(x):
1891
+ return stats.spearmanr(x, y).statistic
1892
+
1893
+ res = permutation_test((x,), statistic1d, permutation_type='pairings',
1894
+ n_resamples=np.inf, alternative=alternative)
1895
+
1896
+ assert_allclose(res.statistic, expected_statistic, rtol=self.rtol)
1897
+ assert_allclose(res.pvalue, expected_pvalue, atol=1e-13)
1898
+
1899
+ @pytest.mark.parametrize("batch", (-1, 0))
1900
+ def test_batch_generator_iv(self, batch):
1901
+ with pytest.raises(ValueError, match="`batch` must be positive."):
1902
+ list(_resampling._batch_generator([1, 2, 3], batch))
1903
+
1904
+ batch_generator_cases = [(range(0), 3, []),
1905
+ (range(6), 3, [[0, 1, 2], [3, 4, 5]]),
1906
+ (range(8), 3, [[0, 1, 2], [3, 4, 5], [6, 7]])]
1907
+
1908
+ @pytest.mark.parametrize("iterable, batch, expected",
1909
+ batch_generator_cases)
1910
+ def test_batch_generator(self, iterable, batch, expected):
1911
+ got = list(_resampling._batch_generator(iterable, batch))
1912
+ assert got == expected
1913
+
1914
+ @pytest.mark.fail_slow(2)
1915
+ def test_finite_precision_statistic(self):
1916
+ # Some statistics return numerically distinct values when the values
1917
+ # should be equal in theory. Test that `permutation_test` accounts
1918
+ # for this in some way.
1919
+ x = [1, 2, 4, 3]
1920
+ y = [2, 4, 6, 8]
1921
+
1922
+ def statistic(x, y):
1923
+ return stats.pearsonr(x, y)[0]
1924
+
1925
+ res = stats.permutation_test((x, y), statistic, vectorized=False,
1926
+ permutation_type='pairings')
1927
+ r, pvalue, null = res.statistic, res.pvalue, res.null_distribution
1928
+
1929
+ correct_p = 2 * np.sum(null >= r - 1e-14) / len(null)
1930
+ assert pvalue == correct_p == 1/3
1931
+ # Compare against other exact correlation tests using R corr.test
1932
+ # options(digits=16)
1933
+ # x = c(1, 2, 4, 3)
1934
+ # y = c(2, 4, 6, 8)
1935
+ # cor.test(x, y, alternative = "t", method = "spearman") # 0.333333333
1936
+ # cor.test(x, y, alternative = "t", method = "kendall") # 0.333333333
1937
+
1938
+
1939
+ def test_all_partitions_concatenated():
1940
+ # make sure that _all_paritions_concatenated produces the correct number
1941
+ # of partitions of the data into samples of the given sizes and that
1942
+ # all are unique
1943
+ n = np.array([3, 2, 4], dtype=int)
1944
+ nc = np.cumsum(n)
1945
+
1946
+ all_partitions = set()
1947
+ counter = 0
1948
+ for partition_concatenated in _resampling._all_partitions_concatenated(n):
1949
+ counter += 1
1950
+ partitioning = np.split(partition_concatenated, nc[:-1])
1951
+ all_partitions.add(tuple([frozenset(i) for i in partitioning]))
1952
+
1953
+ expected = np.prod([special.binom(sum(n[i:]), sum(n[i+1:]))
1954
+ for i in range(len(n)-1)])
1955
+
1956
+ assert_equal(counter, expected)
1957
+ assert_equal(len(all_partitions), expected)
1958
+
1959
+
1960
+ @pytest.mark.parametrize('fun_name',
1961
+ ['bootstrap', 'permutation_test', 'monte_carlo_test'])
1962
+ def test_parameter_vectorized(fun_name):
1963
+ # Check that parameter `vectorized` is working as desired for all
1964
+ # resampling functions. Results don't matter; just don't fail asserts.
1965
+ rng = np.random.default_rng(75245098234592)
1966
+ sample = rng.random(size=10)
1967
+
1968
+ def rvs(size): # needed by `monte_carlo_test`
1969
+ return stats.norm.rvs(size=size, random_state=rng)
1970
+
1971
+ fun_options = {'bootstrap': {'data': (sample,), 'rng': rng,
1972
+ 'method': 'percentile'},
1973
+ 'permutation_test': {'data': (sample,), 'rng': rng,
1974
+ 'permutation_type': 'samples'},
1975
+ 'monte_carlo_test': {'sample': sample, 'rvs': rvs}}
1976
+ common_options = {'n_resamples': 100}
1977
+
1978
+ fun = getattr(stats, fun_name)
1979
+ options = fun_options[fun_name]
1980
+ options.update(common_options)
1981
+
1982
+ def statistic(x, axis):
1983
+ assert x.ndim > 1 or np.array_equal(x, sample)
1984
+ return np.mean(x, axis=axis)
1985
+ fun(statistic=statistic, vectorized=None, **options)
1986
+ fun(statistic=statistic, vectorized=True, **options)
1987
+
1988
+ def statistic(x):
1989
+ assert x.ndim == 1
1990
+ return np.mean(x)
1991
+ fun(statistic=statistic, vectorized=None, **options)
1992
+ fun(statistic=statistic, vectorized=False, **options)
1993
+
1994
+
1995
+ class TestMonteCarloMethod:
1996
+ def test_rvs_and_random_state(self):
1997
+ message = "Use of `rvs` and `rng` are mutually exclusive."
1998
+ rng = np.random.default_rng(34982345)
1999
+ with pytest.raises(ValueError, match=message):
2000
+ stats.MonteCarloMethod(rvs=rng.random, rng=rng)