scipy 1.16.2__cp313-cp313-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.cp313-win_arm64.lib +0 -0
  4. scipy/_cyutility.cp313-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.cp313-win_arm64.lib +0 -0
  13. scipy/_lib/_ccallback_c.cp313-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.cp313-win_arm64.lib +0 -0
  18. scipy/_lib/_fpumode.cp313-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.cp313-win_arm64.lib +0 -0
  23. scipy/_lib/_test_ccallback.cp313-win_arm64.pyd +0 -0
  24. scipy/_lib/_test_deprecation_call.cp313-win_arm64.lib +0 -0
  25. scipy/_lib/_test_deprecation_call.cp313-win_arm64.pyd +0 -0
  26. scipy/_lib/_test_deprecation_def.cp313-win_arm64.lib +0 -0
  27. scipy/_lib/_test_deprecation_def.cp313-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.cp313-win_arm64.lib +0 -0
  35. scipy/_lib/_uarray/_uarray.cp313-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.cp313-win_arm64.lib +0 -0
  101. scipy/_lib/messagestream.cp313-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.cp313-win_arm64.lib +0 -0
  148. scipy/cluster/_hierarchy.cp313-win_arm64.pyd +0 -0
  149. scipy/cluster/_optimal_leaf_ordering.cp313-win_arm64.lib +0 -0
  150. scipy/cluster/_optimal_leaf_ordering.cp313-win_arm64.pyd +0 -0
  151. scipy/cluster/_vq.cp313-win_arm64.lib +0 -0
  152. scipy/cluster/_vq.cp313-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.cp313-win_arm64.lib +0 -0
  193. scipy/fft/_pocketfft/pypocketfft.cp313-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.cp313-win_arm64.lib +0 -0
  215. scipy/fftpack/convolve.cp313-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.cp313-win_arm64.lib +0 -0
  233. scipy/integrate/_dop.cp313-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.cp313-win_arm64.lib +0 -0
  248. scipy/integrate/_lsoda.cp313-win_arm64.pyd +0 -0
  249. scipy/integrate/_ode.py +1395 -0
  250. scipy/integrate/_odepack.cp313-win_arm64.lib +0 -0
  251. scipy/integrate/_odepack.cp313-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.cp313-win_arm64.lib +0 -0
  255. scipy/integrate/_quadpack.cp313-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.cp313-win_arm64.lib +0 -0
  265. scipy/integrate/_test_multivariate.cp313-win_arm64.pyd +0 -0
  266. scipy/integrate/_test_odeint_banded.cp313-win_arm64.lib +0 -0
  267. scipy/integrate/_test_odeint_banded.cp313-win_arm64.pyd +0 -0
  268. scipy/integrate/_vode.cp313-win_arm64.lib +0 -0
  269. scipy/integrate/_vode.cp313-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.cp313-win_arm64.lib +0 -0
  290. scipy/interpolate/_dfitpack.cp313-win_arm64.pyd +0 -0
  291. scipy/interpolate/_dierckx.cp313-win_arm64.lib +0 -0
  292. scipy/interpolate/_dierckx.cp313-win_arm64.pyd +0 -0
  293. scipy/interpolate/_fitpack.cp313-win_arm64.lib +0 -0
  294. scipy/interpolate/_fitpack.cp313-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.cp313-win_arm64.lib +0 -0
  300. scipy/interpolate/_interpnd.cp313-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.cp313-win_arm64.lib +0 -0
  307. scipy/interpolate/_ppoly.cp313-win_arm64.pyd +0 -0
  308. scipy/interpolate/_rbf.py +290 -0
  309. scipy/interpolate/_rbfinterp.py +550 -0
  310. scipy/interpolate/_rbfinterp_pythran.cp313-win_arm64.lib +0 -0
  311. scipy/interpolate/_rbfinterp_pythran.cp313-win_arm64.pyd +0 -0
  312. scipy/interpolate/_rgi.py +764 -0
  313. scipy/interpolate/_rgi_cython.cp313-win_arm64.lib +0 -0
  314. scipy/interpolate/_rgi_cython.cp313-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.cp313-win_arm64.lib +0 -0
  343. scipy/io/_fast_matrix_market/_fmm_core.cp313-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.cp313-win_arm64.lib +0 -0
  355. scipy/io/_test_fortran.cp313-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.cp313-win_arm64.lib +0 -0
  386. scipy/io/matlab/_mio5_utils.cp313-win_arm64.pyd +0 -0
  387. scipy/io/matlab/_mio_utils.cp313-win_arm64.lib +0 -0
  388. scipy/io/matlab/_mio_utils.cp313-win_arm64.pyd +0 -0
  389. scipy/io/matlab/_miobase.py +435 -0
  390. scipy/io/matlab/_streams.cp313-win_arm64.lib +0 -0
  391. scipy/io/matlab/_streams.cp313-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.cp313-win_arm64.lib +0 -0
  623. scipy/linalg/_cythonized_array_utils.cp313-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.cp313-win_arm64.lib +0 -0
  630. scipy/linalg/_decomp_interpolative.cp313-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.cp313-win_arm64.lib +0 -0
  634. scipy/linalg/_decomp_lu_cython.cp313-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.cp313-win_arm64.lib +0 -0
  642. scipy/linalg/_decomp_update.cp313-win_arm64.pyd +0 -0
  643. scipy/linalg/_expm_frechet.py +417 -0
  644. scipy/linalg/_fblas.cp313-win_arm64.lib +0 -0
  645. scipy/linalg/_fblas.cp313-win_arm64.pyd +0 -0
  646. scipy/linalg/_flapack.cp313-win_arm64.lib +0 -0
  647. scipy/linalg/_flapack.cp313-win_arm64.pyd +0 -0
  648. scipy/linalg/_lapack_subroutines.h +1521 -0
  649. scipy/linalg/_linalg_pythran.cp313-win_arm64.lib +0 -0
  650. scipy/linalg/_linalg_pythran.cp313-win_arm64.pyd +0 -0
  651. scipy/linalg/_matfuncs.py +1050 -0
  652. scipy/linalg/_matfuncs_expm.cp313-win_arm64.lib +0 -0
  653. scipy/linalg/_matfuncs_expm.cp313-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.cp313-win_arm64.lib +0 -0
  657. scipy/linalg/_matfuncs_schur_sqrtm.cp313-win_arm64.pyd +0 -0
  658. scipy/linalg/_matfuncs_sqrtm.py +107 -0
  659. scipy/linalg/_matfuncs_sqrtm_triu.cp313-win_arm64.lib +0 -0
  660. scipy/linalg/_matfuncs_sqrtm_triu.cp313-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.cp313-win_arm64.lib +0 -0
  665. scipy/linalg/_solve_toeplitz.cp313-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.cp313-win_arm64.lib +0 -0
  672. scipy/linalg/cython_blas.cp313-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.cp313-win_arm64.lib +0 -0
  676. scipy/linalg/cython_lapack.cp313-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.cp313-win_arm64.lib +0 -0
  728. scipy/ndimage/_ctest.cp313-win_arm64.pyd +0 -0
  729. scipy/ndimage/_cytest.cp313-win_arm64.lib +0 -0
  730. scipy/ndimage/_cytest.cp313-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.cp313-win_arm64.lib +0 -0
  738. scipy/ndimage/_nd_image.cp313-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.cp313-win_arm64.lib +0 -0
  742. scipy/ndimage/_ni_label.cp313-win_arm64.pyd +0 -0
  743. scipy/ndimage/_ni_support.py +139 -0
  744. scipy/ndimage/_rank_filter_1d.cp313-win_arm64.lib +0 -0
  745. scipy/ndimage/_rank_filter_1d.cp313-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.cp313-win_arm64.lib +0 -0
  768. scipy/odr/__odrpack.cp313-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.cp313-win_arm64.lib +0 -0
  780. scipy/optimize/_bglu_dense.cp313-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.cp313-win_arm64.lib +0 -0
  790. scipy/optimize/_direct.cp313-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.cp313-win_arm64.lib +0 -0
  795. scipy/optimize/_group_columns.cp313-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.cp313-win_arm64.lib +0 -0
  799. scipy/optimize/_highspy/_core.cp313-win_arm64.pyd +0 -0
  800. scipy/optimize/_highspy/_highs_options.cp313-win_arm64.lib +0 -0
  801. scipy/optimize/_highspy/_highs_options.cp313-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.cp313-win_arm64.lib +0 -0
  805. scipy/optimize/_lbfgsb.cp313-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.cp313-win_arm64.lib +0 -0
  816. scipy/optimize/_lsap.cp313-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.cp313-win_arm64.lib +0 -0
  822. scipy/optimize/_lsq/givens_elimination.cp313-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.cp313-win_arm64.lib +0 -0
  830. scipy/optimize/_minpack.cp313-win_arm64.pyd +0 -0
  831. scipy/optimize/_minpack_py.py +1178 -0
  832. scipy/optimize/_moduleTNC.cp313-win_arm64.lib +0 -0
  833. scipy/optimize/_moduleTNC.cp313-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.cp313-win_arm64.lib +0 -0
  839. scipy/optimize/_pava_pybind.cp313-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.cp313-win_arm64.lib +0 -0
  850. scipy/optimize/_slsqplib.cp313-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.cp313-win_arm64.lib +0 -0
  855. scipy/optimize/_trlib/_trlib.cp313-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.cp313-win_arm64.lib +0 -0
  877. scipy/optimize/_zeros.cp313-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.cp313-win_arm64.lib +0 -0
  882. scipy/optimize/cython_optimize/_zeros.cp313-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.cp313-win_arm64.lib +0 -0
  953. scipy/signal/_max_len_seq_inner.cp313-win_arm64.pyd +0 -0
  954. scipy/signal/_peak_finding.py +1310 -0
  955. scipy/signal/_peak_finding_utils.cp313-win_arm64.lib +0 -0
  956. scipy/signal/_peak_finding_utils.cp313-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.cp313-win_arm64.lib +0 -0
  963. scipy/signal/_sigtools.cp313-win_arm64.pyd +0 -0
  964. scipy/signal/_sosfilt.cp313-win_arm64.lib +0 -0
  965. scipy/signal/_sosfilt.cp313-win_arm64.pyd +0 -0
  966. scipy/signal/_spectral_py.py +2471 -0
  967. scipy/signal/_spline.cp313-win_arm64.lib +0 -0
  968. scipy/signal/_spline.cp313-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.cp313-win_arm64.lib +0 -0
  974. scipy/signal/_upfirdn_apply.cp313-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.cp313-win_arm64.lib +0 -0
  1021. scipy/sparse/_csparsetools.cp313-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.cp313-win_arm64.lib +0 -0
  1032. scipy/sparse/_sparsetools.cp313-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.cp313-win_arm64.lib +0 -0
  1043. scipy/sparse/csgraph/_flow.cp313-win_arm64.pyd +0 -0
  1044. scipy/sparse/csgraph/_laplacian.py +563 -0
  1045. scipy/sparse/csgraph/_matching.cp313-win_arm64.lib +0 -0
  1046. scipy/sparse/csgraph/_matching.cp313-win_arm64.pyd +0 -0
  1047. scipy/sparse/csgraph/_min_spanning_tree.cp313-win_arm64.lib +0 -0
  1048. scipy/sparse/csgraph/_min_spanning_tree.cp313-win_arm64.pyd +0 -0
  1049. scipy/sparse/csgraph/_reordering.cp313-win_arm64.lib +0 -0
  1050. scipy/sparse/csgraph/_reordering.cp313-win_arm64.pyd +0 -0
  1051. scipy/sparse/csgraph/_shortest_path.cp313-win_arm64.lib +0 -0
  1052. scipy/sparse/csgraph/_shortest_path.cp313-win_arm64.pyd +0 -0
  1053. scipy/sparse/csgraph/_tools.cp313-win_arm64.lib +0 -0
  1054. scipy/sparse/csgraph/_tools.cp313-win_arm64.pyd +0 -0
  1055. scipy/sparse/csgraph/_traversal.cp313-win_arm64.lib +0 -0
  1056. scipy/sparse/csgraph/_traversal.cp313-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.cp313-win_arm64.lib +0 -0
  1079. scipy/sparse/linalg/_dsolve/_superlu.cp313-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.cp313-win_arm64.lib +0 -0
  1089. scipy/sparse/linalg/_eigen/arpack/_arpack.cp313-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.cp313-win_arm64.lib +0 -0
  1122. scipy/sparse/linalg/_propack/_cpropack.cp313-win_arm64.pyd +0 -0
  1123. scipy/sparse/linalg/_propack/_dpropack.cp313-win_arm64.lib +0 -0
  1124. scipy/sparse/linalg/_propack/_dpropack.cp313-win_arm64.pyd +0 -0
  1125. scipy/sparse/linalg/_propack/_spropack.cp313-win_arm64.lib +0 -0
  1126. scipy/sparse/linalg/_propack/_spropack.cp313-win_arm64.pyd +0 -0
  1127. scipy/sparse/linalg/_propack/_zpropack.cp313-win_arm64.lib +0 -0
  1128. scipy/sparse/linalg/_propack/_zpropack.cp313-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.cp313-win_arm64.lib +0 -0
  1170. scipy/spatial/_ckdtree.cp313-win_arm64.pyd +0 -0
  1171. scipy/spatial/_distance_pybind.cp313-win_arm64.lib +0 -0
  1172. scipy/spatial/_distance_pybind.cp313-win_arm64.pyd +0 -0
  1173. scipy/spatial/_distance_wrap.cp313-win_arm64.lib +0 -0
  1174. scipy/spatial/_distance_wrap.cp313-win_arm64.pyd +0 -0
  1175. scipy/spatial/_geometric_slerp.py +238 -0
  1176. scipy/spatial/_hausdorff.cp313-win_arm64.lib +0 -0
  1177. scipy/spatial/_hausdorff.cp313-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.cp313-win_arm64.lib +0 -0
  1182. scipy/spatial/_qhull.cp313-win_arm64.pyd +0 -0
  1183. scipy/spatial/_qhull.pyi +213 -0
  1184. scipy/spatial/_spherical_voronoi.py +341 -0
  1185. scipy/spatial/_voronoi.cp313-win_arm64.lib +0 -0
  1186. scipy/spatial/_voronoi.cp313-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.cp313-win_arm64.lib +0 -0
  1236. scipy/spatial/transform/_rigid_transform.cp313-win_arm64.pyd +0 -0
  1237. scipy/spatial/transform/_rotation.cp313-win_arm64.lib +0 -0
  1238. scipy/spatial/transform/_rotation.cp313-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.cp313-win_arm64.lib +0 -0
  1252. scipy/special/_comb.cp313-win_arm64.pyd +0 -0
  1253. scipy/special/_ellip_harm.py +214 -0
  1254. scipy/special/_ellip_harm_2.cp313-win_arm64.lib +0 -0
  1255. scipy/special/_ellip_harm_2.cp313-win_arm64.pyd +0 -0
  1256. scipy/special/_gufuncs.cp313-win_arm64.lib +0 -0
  1257. scipy/special/_gufuncs.cp313-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.cp313-win_arm64.lib +0 -0
  1281. scipy/special/_specfun.cp313-win_arm64.pyd +0 -0
  1282. scipy/special/_special_ufuncs.cp313-win_arm64.lib +0 -0
  1283. scipy/special/_special_ufuncs.cp313-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.cp313-win_arm64.lib +0 -0
  1288. scipy/special/_test_internal.cp313-win_arm64.pyd +0 -0
  1289. scipy/special/_test_internal.pyi +9 -0
  1290. scipy/special/_testutils.py +321 -0
  1291. scipy/special/_ufuncs.cp313-win_arm64.lib +0 -0
  1292. scipy/special/_ufuncs.cp313-win_arm64.pyd +0 -0
  1293. scipy/special/_ufuncs.pyi +522 -0
  1294. scipy/special/_ufuncs.pyx +13173 -0
  1295. scipy/special/_ufuncs_cxx.cp313-win_arm64.lib +0 -0
  1296. scipy/special/_ufuncs_cxx.cp313-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.cp313-win_arm64.lib +0 -0
  1304. scipy/special/cython_special.cp313-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.cp313-win_arm64.lib +0 -0
  1376. scipy/stats/_ansari_swilk_statistics.cp313-win_arm64.pyd +0 -0
  1377. scipy/stats/_axis_nan_policy.py +692 -0
  1378. scipy/stats/_biasedurn.cp313-win_arm64.lib +0 -0
  1379. scipy/stats/_biasedurn.cp313-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.cp313-win_arm64.lib +0 -0
  1404. scipy/stats/_levy_stable/levyst.cp313-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.cp313-win_arm64.lib +0 -0
  1418. scipy/stats/_qmc_cy.cp313-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.cp313-win_arm64.lib +0 -0
  1422. scipy/stats/_qmvnt_cy.cp313-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.cp313-win_arm64.lib +0 -0
  1426. scipy/stats/_rcont/rcont.cp313-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.cp313-win_arm64.lib +0 -0
  1433. scipy/stats/_sobol.cp313-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.cp313-win_arm64.lib +0 -0
  1437. scipy/stats/_stats.cp313-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.cp313-win_arm64.lib +0 -0
  1442. scipy/stats/_stats_pythran.cp313-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.cp313-win_arm64.lib +0 -0
  1447. scipy/stats/_unuran/unuran_wrapper.cp313-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,1991 @@
1
+ from itertools import product
2
+
3
+ import numpy as np
4
+ import random
5
+ import functools
6
+ import pytest
7
+ from numpy.testing import (assert_, assert_equal, assert_allclose,
8
+ assert_almost_equal) # avoid new uses
9
+ from pytest import raises as assert_raises
10
+
11
+ import scipy.stats as stats
12
+ from scipy.stats import distributions
13
+ from scipy.stats._hypotests import (epps_singleton_2samp, cramervonmises,
14
+ _cdf_cvm, cramervonmises_2samp,
15
+ _pval_cvm_2samp_exact, barnard_exact,
16
+ boschloo_exact)
17
+ from scipy.stats._mannwhitneyu import mannwhitneyu, _mwu_state, _MWU
18
+ from .common_tests import check_named_results
19
+ from scipy._lib._testutils import _TestPythranFunc
20
+ from scipy.stats._axis_nan_policy import SmallSampleWarning, too_small_1d_not_omit
21
+
22
+
23
+ class TestEppsSingleton:
24
+ def test_statistic_1(self):
25
+ # first example in Goerg & Kaiser, also in original paper of
26
+ # Epps & Singleton. Note: values do not match exactly, the
27
+ # value of the interquartile range varies depending on how
28
+ # quantiles are computed
29
+ x = np.array([-0.35, 2.55, 1.73, 0.73, 0.35,
30
+ 2.69, 0.46, -0.94, -0.37, 12.07])
31
+ y = np.array([-1.15, -0.15, 2.48, 3.25, 3.71,
32
+ 4.29, 5.00, 7.74, 8.38, 8.60])
33
+ w, p = epps_singleton_2samp(x, y)
34
+ assert_almost_equal(w, 15.14, decimal=1)
35
+ assert_almost_equal(p, 0.00442, decimal=3)
36
+
37
+ def test_statistic_2(self):
38
+ # second example in Goerg & Kaiser, again not a perfect match
39
+ x = np.array((0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 5, 6, 10,
40
+ 10, 10, 10))
41
+ y = np.array((10, 4, 0, 5, 10, 10, 0, 5, 6, 7, 10, 3, 1, 7, 0, 8, 1,
42
+ 5, 8, 10))
43
+ w, p = epps_singleton_2samp(x, y)
44
+ assert_allclose(w, 8.900, atol=0.001)
45
+ assert_almost_equal(p, 0.06364, decimal=3)
46
+
47
+ def test_epps_singleton_array_like(self):
48
+ np.random.seed(1234)
49
+ x, y = np.arange(30), np.arange(28)
50
+
51
+ w1, p1 = epps_singleton_2samp(list(x), list(y))
52
+ w2, p2 = epps_singleton_2samp(tuple(x), tuple(y))
53
+ w3, p3 = epps_singleton_2samp(x, y)
54
+
55
+ assert_(w1 == w2 == w3)
56
+ assert_(p1 == p2 == p3)
57
+
58
+ def test_epps_singleton_size(self):
59
+ # warns if sample contains fewer than 5 elements
60
+ x, y = (1, 2, 3, 4), np.arange(10)
61
+ with pytest.warns(SmallSampleWarning, match=too_small_1d_not_omit):
62
+ res = epps_singleton_2samp(x, y)
63
+ assert_equal(res.statistic, np.nan)
64
+ assert_equal(res.pvalue, np.nan)
65
+
66
+ def test_epps_singleton_nonfinite(self):
67
+ # raise error if there are non-finite values
68
+ x, y = (1, 2, 3, 4, 5, np.inf), np.arange(10)
69
+ assert_raises(ValueError, epps_singleton_2samp, x, y)
70
+
71
+ def test_names(self):
72
+ x, y = np.arange(20), np.arange(30)
73
+ res = epps_singleton_2samp(x, y)
74
+ attributes = ('statistic', 'pvalue')
75
+ check_named_results(res, attributes)
76
+
77
+
78
+ class TestCvm:
79
+ # the expected values of the cdfs are taken from Table 1 in
80
+ # Csorgo / Faraway: The Exact and Asymptotic Distribution of
81
+ # Cramér-von Mises Statistics, 1996.
82
+ def test_cdf_4(self):
83
+ assert_allclose(
84
+ _cdf_cvm([0.02983, 0.04111, 0.12331, 0.94251], 4),
85
+ [0.01, 0.05, 0.5, 0.999],
86
+ atol=1e-4)
87
+
88
+ def test_cdf_10(self):
89
+ assert_allclose(
90
+ _cdf_cvm([0.02657, 0.03830, 0.12068, 0.56643], 10),
91
+ [0.01, 0.05, 0.5, 0.975],
92
+ atol=1e-4)
93
+
94
+ def test_cdf_1000(self):
95
+ assert_allclose(
96
+ _cdf_cvm([0.02481, 0.03658, 0.11889, 1.16120], 1000),
97
+ [0.01, 0.05, 0.5, 0.999],
98
+ atol=1e-4)
99
+
100
+ def test_cdf_inf(self):
101
+ assert_allclose(
102
+ _cdf_cvm([0.02480, 0.03656, 0.11888, 1.16204]),
103
+ [0.01, 0.05, 0.5, 0.999],
104
+ atol=1e-4)
105
+
106
+ def test_cdf_support(self):
107
+ # cdf has support on [1/(12*n), n/3]
108
+ assert_equal(_cdf_cvm([1/(12*533), 533/3], 533), [0, 1])
109
+ assert_equal(_cdf_cvm([1/(12*(27 + 1)), (27 + 1)/3], 27), [0, 1])
110
+
111
+ def test_cdf_large_n(self):
112
+ # test that asymptotic cdf and cdf for large samples are close
113
+ assert_allclose(
114
+ _cdf_cvm([0.02480, 0.03656, 0.11888, 1.16204, 100], 10000),
115
+ _cdf_cvm([0.02480, 0.03656, 0.11888, 1.16204, 100]),
116
+ atol=1e-4)
117
+
118
+ def test_large_x(self):
119
+ # for large values of x and n, the series used to compute the cdf
120
+ # converges slowly.
121
+ # this leads to bug in R package goftest and MAPLE code that is
122
+ # the basis of the implementation in scipy
123
+ # note: cdf = 1 for x >= 1000/3 and n = 1000
124
+ assert_(0.99999 < _cdf_cvm(333.3, 1000) < 1.0)
125
+ assert_(0.99999 < _cdf_cvm(333.3) < 1.0)
126
+
127
+ def test_low_p(self):
128
+ # _cdf_cvm can return values larger than 1. In that case, we just
129
+ # return a p-value of zero.
130
+ n = 12
131
+ res = cramervonmises(np.ones(n)*0.8, 'norm')
132
+ assert_(_cdf_cvm(res.statistic, n) > 1.0)
133
+ assert_equal(res.pvalue, 0)
134
+
135
+ @pytest.mark.parametrize('x', [(), [1.5]])
136
+ def test_invalid_input(self, x):
137
+ with pytest.warns(SmallSampleWarning, match=too_small_1d_not_omit):
138
+ res = cramervonmises(x, "norm")
139
+ assert_equal(res.statistic, np.nan)
140
+ assert_equal(res.pvalue, np.nan)
141
+
142
+ def test_values_R(self):
143
+ # compared against R package goftest, version 1.1.1
144
+ # goftest::cvm.test(c(-1.7, 2, 0, 1.3, 4, 0.1, 0.6), "pnorm")
145
+ res = cramervonmises([-1.7, 2, 0, 1.3, 4, 0.1, 0.6], "norm")
146
+ assert_allclose(res.statistic, 0.288156, atol=1e-6)
147
+ assert_allclose(res.pvalue, 0.1453465, atol=1e-6)
148
+
149
+ # goftest::cvm.test(c(-1.7, 2, 0, 1.3, 4, 0.1, 0.6),
150
+ # "pnorm", mean = 3, sd = 1.5)
151
+ res = cramervonmises([-1.7, 2, 0, 1.3, 4, 0.1, 0.6], "norm", (3, 1.5))
152
+ assert_allclose(res.statistic, 0.9426685, atol=1e-6)
153
+ assert_allclose(res.pvalue, 0.002026417, atol=1e-6)
154
+
155
+ # goftest::cvm.test(c(1, 2, 5, 1.4, 0.14, 11, 13, 0.9, 7.5), "pexp")
156
+ res = cramervonmises([1, 2, 5, 1.4, 0.14, 11, 13, 0.9, 7.5], "expon")
157
+ assert_allclose(res.statistic, 0.8421854, atol=1e-6)
158
+ assert_allclose(res.pvalue, 0.004433406, atol=1e-6)
159
+
160
+ def test_callable_cdf(self):
161
+ x, args = np.arange(5), (1.4, 0.7)
162
+ r1 = cramervonmises(x, distributions.expon.cdf)
163
+ r2 = cramervonmises(x, "expon")
164
+ assert_equal((r1.statistic, r1.pvalue), (r2.statistic, r2.pvalue))
165
+
166
+ r1 = cramervonmises(x, distributions.beta.cdf, args)
167
+ r2 = cramervonmises(x, "beta", args)
168
+ assert_equal((r1.statistic, r1.pvalue), (r2.statistic, r2.pvalue))
169
+
170
+
171
+ class TestMannWhitneyU:
172
+
173
+ # All magic numbers are from R wilcox.test unless otherwise specified
174
+ # https://rdrr.io/r/stats/wilcox.test.html
175
+
176
+ # --- Test Input Validation ---
177
+
178
+ @pytest.mark.parametrize('kwargs_update', [{'x': []}, {'y': []},
179
+ {'x': [], 'y': []}])
180
+ def test_empty(self, kwargs_update):
181
+ x = np.array([1, 2]) # generic, valid inputs
182
+ y = np.array([3, 4])
183
+ kwargs = dict(x=x, y=y)
184
+ kwargs.update(kwargs_update)
185
+ with pytest.warns(SmallSampleWarning, match=too_small_1d_not_omit):
186
+ res = mannwhitneyu(**kwargs)
187
+ assert_equal(res.statistic, np.nan)
188
+ assert_equal(res.pvalue, np.nan)
189
+
190
+ def test_input_validation(self):
191
+ x = np.array([1, 2]) # generic, valid inputs
192
+ y = np.array([3, 4])
193
+ with assert_raises(ValueError, match="`use_continuity` must be one"):
194
+ mannwhitneyu(x, y, use_continuity='ekki')
195
+ with assert_raises(ValueError, match="`alternative` must be one of"):
196
+ mannwhitneyu(x, y, alternative='ekki')
197
+ with assert_raises(ValueError, match="`axis` must be an integer"):
198
+ mannwhitneyu(x, y, axis=1.5)
199
+ with assert_raises(ValueError, match="`method` must be one of"):
200
+ mannwhitneyu(x, y, method='ekki')
201
+
202
+ def test_auto(self):
203
+ # Test that default method ('auto') chooses intended method
204
+
205
+ rng = np.random.RandomState(1)
206
+ n = 8 # threshold to switch from exact to asymptotic
207
+
208
+ # both inputs are smaller than threshold; should use exact
209
+ x = rng.rand(n-1)
210
+ y = rng.rand(n-1)
211
+ auto = mannwhitneyu(x, y)
212
+ asymptotic = mannwhitneyu(x, y, method='asymptotic')
213
+ exact = mannwhitneyu(x, y, method='exact')
214
+ assert auto.pvalue == exact.pvalue
215
+ assert auto.pvalue != asymptotic.pvalue
216
+
217
+ # one input is smaller than threshold; should use exact
218
+ x = rng.rand(n-1)
219
+ y = rng.rand(n+1)
220
+ auto = mannwhitneyu(x, y)
221
+ asymptotic = mannwhitneyu(x, y, method='asymptotic')
222
+ exact = mannwhitneyu(x, y, method='exact')
223
+ assert auto.pvalue == exact.pvalue
224
+ assert auto.pvalue != asymptotic.pvalue
225
+
226
+ # other input is smaller than threshold; should use exact
227
+ auto = mannwhitneyu(y, x)
228
+ asymptotic = mannwhitneyu(x, y, method='asymptotic')
229
+ exact = mannwhitneyu(x, y, method='exact')
230
+ assert auto.pvalue == exact.pvalue
231
+ assert auto.pvalue != asymptotic.pvalue
232
+
233
+ # both inputs are larger than threshold; should use asymptotic
234
+ x = rng.rand(n+1)
235
+ y = rng.rand(n+1)
236
+ auto = mannwhitneyu(x, y)
237
+ asymptotic = mannwhitneyu(x, y, method='asymptotic')
238
+ exact = mannwhitneyu(x, y, method='exact')
239
+ assert auto.pvalue != exact.pvalue
240
+ assert auto.pvalue == asymptotic.pvalue
241
+
242
+ # both inputs are smaller than threshold, but there is a tie
243
+ # should use asymptotic
244
+ x = rng.rand(n-1)
245
+ y = rng.rand(n-1)
246
+ y[3] = x[3]
247
+ auto = mannwhitneyu(x, y)
248
+ asymptotic = mannwhitneyu(x, y, method='asymptotic')
249
+ exact = mannwhitneyu(x, y, method='exact')
250
+ assert auto.pvalue != exact.pvalue
251
+ assert auto.pvalue == asymptotic.pvalue
252
+
253
+ # --- Test Basic Functionality ---
254
+
255
+ x = [210.052110, 110.190630, 307.918612]
256
+ y = [436.08811482466416, 416.37397329768191, 179.96975939463582,
257
+ 197.8118754228619, 34.038757281225756, 138.54220550921517,
258
+ 128.7769351470246, 265.92721427951852, 275.6617533155341,
259
+ 592.34083395416258, 448.73177590617018, 300.61495185038905,
260
+ 187.97508449019588]
261
+
262
+ # This test was written for mann_whitney_u in gh-4933.
263
+ # Originally, the p-values for alternatives were swapped;
264
+ # this has been corrected and the tests have been refactored for
265
+ # compactness, but otherwise the tests are unchanged.
266
+ # R code for comparison, e.g.:
267
+ # options(digits = 16)
268
+ # x = c(210.052110, 110.190630, 307.918612)
269
+ # y = c(436.08811482466416, 416.37397329768191, 179.96975939463582,
270
+ # 197.8118754228619, 34.038757281225756, 138.54220550921517,
271
+ # 128.7769351470246, 265.92721427951852, 275.6617533155341,
272
+ # 592.34083395416258, 448.73177590617018, 300.61495185038905,
273
+ # 187.97508449019588)
274
+ # wilcox.test(x, y, alternative="g", exact=TRUE)
275
+ cases_basic = [[{"alternative": 'two-sided', "method": "asymptotic"},
276
+ (16, 0.6865041817876)],
277
+ [{"alternative": 'less', "method": "asymptotic"},
278
+ (16, 0.3432520908938)],
279
+ [{"alternative": 'greater', "method": "asymptotic"},
280
+ (16, 0.7047591913255)],
281
+ [{"alternative": 'two-sided', "method": "exact"},
282
+ (16, 0.7035714285714)],
283
+ [{"alternative": 'less', "method": "exact"},
284
+ (16, 0.3517857142857)],
285
+ [{"alternative": 'greater', "method": "exact"},
286
+ (16, 0.6946428571429)]]
287
+
288
+ @pytest.mark.parametrize(("kwds", "expected"), cases_basic)
289
+ def test_basic(self, kwds, expected):
290
+ res = mannwhitneyu(self.x, self.y, **kwds)
291
+ assert_allclose(res, expected)
292
+
293
+ cases_continuity = [[{"alternative": 'two-sided', "use_continuity": True},
294
+ (23, 0.6865041817876)],
295
+ [{"alternative": 'less', "use_continuity": True},
296
+ (23, 0.7047591913255)],
297
+ [{"alternative": 'greater', "use_continuity": True},
298
+ (23, 0.3432520908938)],
299
+ [{"alternative": 'two-sided', "use_continuity": False},
300
+ (23, 0.6377328900502)],
301
+ [{"alternative": 'less', "use_continuity": False},
302
+ (23, 0.6811335549749)],
303
+ [{"alternative": 'greater', "use_continuity": False},
304
+ (23, 0.3188664450251)]]
305
+
306
+ @pytest.mark.parametrize(("kwds", "expected"), cases_continuity)
307
+ def test_continuity(self, kwds, expected):
308
+ # When x and y are interchanged, less and greater p-values should
309
+ # swap (compare to above). This wouldn't happen if the continuity
310
+ # correction were applied in the wrong direction. Note that less and
311
+ # greater p-values do not sum to 1 when continuity correction is on,
312
+ # which is what we'd expect. Also check that results match R when
313
+ # continuity correction is turned off.
314
+ # Note that method='asymptotic' -> exact=FALSE
315
+ # and use_continuity=False -> correct=FALSE, e.g.:
316
+ # wilcox.test(x, y, alternative="t", exact=FALSE, correct=FALSE)
317
+ res = mannwhitneyu(self.y, self.x, method='asymptotic', **kwds)
318
+ assert_allclose(res, expected)
319
+
320
+ def test_tie_correct(self):
321
+ # Test tie correction against R's wilcox.test
322
+ # options(digits = 16)
323
+ # x = c(1, 2, 3, 4)
324
+ # y = c(1, 2, 3, 4, 5)
325
+ # wilcox.test(x, y, exact=FALSE)
326
+ x = [1, 2, 3, 4]
327
+ y0 = np.array([1, 2, 3, 4, 5])
328
+ dy = np.array([0, 1, 0, 1, 0])*0.01
329
+ dy2 = np.array([0, 0, 1, 0, 0])*0.01
330
+ y = [y0-0.01, y0-dy, y0-dy2, y0, y0+dy2, y0+dy, y0+0.01]
331
+ res = mannwhitneyu(x, y, axis=-1, method="asymptotic")
332
+ U_expected = [10, 9, 8.5, 8, 7.5, 7, 6]
333
+ p_expected = [1, 0.9017048037317, 0.804080657472, 0.7086240584439,
334
+ 0.6197963884941, 0.5368784563079, 0.3912672792826]
335
+ assert_equal(res.statistic, U_expected)
336
+ assert_allclose(res.pvalue, p_expected)
337
+
338
+ # --- Test Exact Distribution of U ---
339
+
340
+ # These are tabulated values of the CDF of the exact distribution of
341
+ # the test statistic from pg 52 of reference [1] (Mann-Whitney Original)
342
+ pn3 = {1: [0.25, 0.5, 0.75], 2: [0.1, 0.2, 0.4, 0.6],
343
+ 3: [0.05, .1, 0.2, 0.35, 0.5, 0.65]}
344
+ pn4 = {1: [0.2, 0.4, 0.6], 2: [0.067, 0.133, 0.267, 0.4, 0.6],
345
+ 3: [0.028, 0.057, 0.114, 0.2, .314, 0.429, 0.571],
346
+ 4: [0.014, 0.029, 0.057, 0.1, 0.171, 0.243, 0.343, 0.443, 0.557]}
347
+ pm5 = {1: [0.167, 0.333, 0.5, 0.667],
348
+ 2: [0.047, 0.095, 0.19, 0.286, 0.429, 0.571],
349
+ 3: [0.018, 0.036, 0.071, 0.125, 0.196, 0.286, 0.393, 0.5, 0.607],
350
+ 4: [0.008, 0.016, 0.032, 0.056, 0.095, 0.143,
351
+ 0.206, 0.278, 0.365, 0.452, 0.548],
352
+ 5: [0.004, 0.008, 0.016, 0.028, 0.048, 0.075, 0.111,
353
+ 0.155, 0.21, 0.274, 0.345, .421, 0.5, 0.579]}
354
+ pm6 = {1: [0.143, 0.286, 0.428, 0.571],
355
+ 2: [0.036, 0.071, 0.143, 0.214, 0.321, 0.429, 0.571],
356
+ 3: [0.012, 0.024, 0.048, 0.083, 0.131,
357
+ 0.19, 0.274, 0.357, 0.452, 0.548],
358
+ 4: [0.005, 0.01, 0.019, 0.033, 0.057, 0.086, 0.129,
359
+ 0.176, 0.238, 0.305, 0.381, 0.457, 0.543], # the last element
360
+ # of the previous list, 0.543, has been modified from 0.545;
361
+ # I assume it was a typo
362
+ 5: [0.002, 0.004, 0.009, 0.015, 0.026, 0.041, 0.063, 0.089,
363
+ 0.123, 0.165, 0.214, 0.268, 0.331, 0.396, 0.465, 0.535],
364
+ 6: [0.001, 0.002, 0.004, 0.008, 0.013, 0.021, 0.032, 0.047,
365
+ 0.066, 0.09, 0.12, 0.155, 0.197, 0.242, 0.294, 0.350,
366
+ 0.409, 0.469, 0.531]}
367
+
368
+ def test_exact_distribution(self):
369
+ # I considered parametrize. I decided against it.
370
+ setattr(_mwu_state, 's', _MWU(0, 0))
371
+
372
+ p_tables = {3: self.pn3, 4: self.pn4, 5: self.pm5, 6: self.pm6}
373
+ for n, table in p_tables.items():
374
+ for m, p in table.items():
375
+ # check p-value against table
376
+ u = np.arange(0, len(p))
377
+ _mwu_state.s.set_shapes(m, n)
378
+ assert_allclose(_mwu_state.s.cdf(k=u), p, atol=1e-3)
379
+
380
+ # check identity CDF + SF - PMF = 1
381
+ # ( In this implementation, SF(U) includes PMF(U) )
382
+ u2 = np.arange(0, m*n+1)
383
+ assert_allclose(_mwu_state.s.cdf(k=u2)
384
+ + _mwu_state.s.sf(k=u2)
385
+ - _mwu_state.s.pmf(k=u2), 1)
386
+
387
+ # check symmetry about mean of U, i.e. pmf(U) = pmf(m*n-U)
388
+ pmf = _mwu_state.s.pmf(k=u2)
389
+ assert_allclose(pmf, pmf[::-1])
390
+
391
+ # check symmetry w.r.t. interchange of m, n
392
+ _mwu_state.s.set_shapes(n, m)
393
+ pmf2 = _mwu_state.s.pmf(k=u2)
394
+ assert_allclose(pmf, pmf2)
395
+
396
+ def test_asymptotic_behavior(self):
397
+ rng = np.random.default_rng(12543)
398
+
399
+ # for small samples, the asymptotic test is not very accurate
400
+ x = rng.random(5)
401
+ y = rng.random(5)
402
+ res1 = mannwhitneyu(x, y, method="exact")
403
+ res2 = mannwhitneyu(x, y, method="asymptotic")
404
+ assert res1.statistic == res2.statistic
405
+ assert np.abs(res1.pvalue - res2.pvalue) > 1e-2
406
+
407
+ # for large samples, they agree reasonably well
408
+ x = rng.random(40)
409
+ y = rng.random(40)
410
+ res1 = mannwhitneyu(x, y, method="exact")
411
+ res2 = mannwhitneyu(x, y, method="asymptotic")
412
+ assert res1.statistic == res2.statistic
413
+ assert np.abs(res1.pvalue - res2.pvalue) < 1e-3
414
+
415
+ # --- Test Corner Cases ---
416
+
417
+ def test_exact_U_equals_mean(self):
418
+ # Test U == m*n/2 with exact method
419
+ # Without special treatment, two-sided p-value > 1 because both
420
+ # one-sided p-values are > 0.5
421
+ res_l = mannwhitneyu([1, 2, 3], [1.5, 2.5], alternative="less",
422
+ method="exact")
423
+ res_g = mannwhitneyu([1, 2, 3], [1.5, 2.5], alternative="greater",
424
+ method="exact")
425
+ assert_equal(res_l.pvalue, res_g.pvalue)
426
+ assert res_l.pvalue > 0.5
427
+
428
+ res = mannwhitneyu([1, 2, 3], [1.5, 2.5], alternative="two-sided",
429
+ method="exact")
430
+ assert_equal(res, (3, 1))
431
+ # U == m*n/2 for asymptotic case tested in test_gh_2118
432
+ # The reason it's tricky for the asymptotic test has to do with
433
+ # continuity correction.
434
+
435
+ cases_scalar = [[{"alternative": 'two-sided', "method": "asymptotic"},
436
+ (0, 1)],
437
+ [{"alternative": 'less', "method": "asymptotic"},
438
+ (0, 0.5)],
439
+ [{"alternative": 'greater', "method": "asymptotic"},
440
+ (0, 0.977249868052)],
441
+ [{"alternative": 'two-sided', "method": "exact"}, (0, 1)],
442
+ [{"alternative": 'less', "method": "exact"}, (0, 0.5)],
443
+ [{"alternative": 'greater', "method": "exact"}, (0, 1)]]
444
+
445
+ @pytest.mark.parametrize(("kwds", "result"), cases_scalar)
446
+ def test_scalar_data(self, kwds, result):
447
+ # just making sure scalars work
448
+ assert_allclose(mannwhitneyu(1, 2, **kwds), result)
449
+
450
+ def test_equal_scalar_data(self):
451
+ # when two scalars are equal, there is an -0.5/0 in the asymptotic
452
+ # approximation. R gives pvalue=1.0 for alternatives 'less' and
453
+ # 'greater' but NA for 'two-sided'. I don't see why, so I don't
454
+ # see a need for a special case to match that behavior.
455
+ assert_equal(mannwhitneyu(1, 1, method="exact"), (0.5, 1))
456
+ assert_equal(mannwhitneyu(1, 1, method="asymptotic"), (0.5, 1))
457
+
458
+ # without continuity correction, this becomes 0/0, which really
459
+ # is undefined
460
+ assert_equal(mannwhitneyu(1, 1, method="asymptotic",
461
+ use_continuity=False), (0.5, np.nan))
462
+
463
+ # --- Test Enhancements / Bug Reports ---
464
+
465
+ @pytest.mark.parametrize("method", ["asymptotic", "exact"])
466
+ def test_gh_12837_11113(self, method):
467
+ # Test that behavior for broadcastable nd arrays is appropriate:
468
+ # output shape is correct and all values are equal to when the test
469
+ # is performed on one pair of samples at a time.
470
+ # Tests that gh-12837 and gh-11113 (requests for n-d input)
471
+ # are resolved
472
+ np.random.seed(0)
473
+
474
+ # arrays are broadcastable except for axis = -3
475
+ axis = -3
476
+ m, n = 7, 10 # sample sizes
477
+ x = np.random.rand(m, 3, 8)
478
+ y = np.random.rand(6, n, 1, 8) + 0.1
479
+ res = mannwhitneyu(x, y, method=method, axis=axis)
480
+
481
+ shape = (6, 3, 8) # appropriate shape of outputs, given inputs
482
+ assert res.pvalue.shape == shape
483
+ assert res.statistic.shape == shape
484
+
485
+ # move axis of test to end for simplicity
486
+ x, y = np.moveaxis(x, axis, -1), np.moveaxis(y, axis, -1)
487
+
488
+ x = x[None, ...] # give x a zeroth dimension
489
+ assert x.ndim == y.ndim
490
+
491
+ x = np.broadcast_to(x, shape + (m,))
492
+ y = np.broadcast_to(y, shape + (n,))
493
+ assert x.shape[:-1] == shape
494
+ assert y.shape[:-1] == shape
495
+
496
+ # loop over pairs of samples
497
+ statistics = np.zeros(shape)
498
+ pvalues = np.zeros(shape)
499
+ for indices in product(*[range(i) for i in shape]):
500
+ xi = x[indices]
501
+ yi = y[indices]
502
+ temp = mannwhitneyu(xi, yi, method=method)
503
+ statistics[indices] = temp.statistic
504
+ pvalues[indices] = temp.pvalue
505
+
506
+ np.testing.assert_equal(res.pvalue, pvalues)
507
+ np.testing.assert_equal(res.statistic, statistics)
508
+
509
+ def test_gh_11355(self):
510
+ # Test for correct behavior with NaN/Inf in input
511
+ x = [1, 2, 3, 4]
512
+ y = [3, 6, 7, 8, 9, 3, 2, 1, 4, 4, 5]
513
+ res1 = mannwhitneyu(x, y)
514
+
515
+ # Inf is not a problem. This is a rank test, and it's the largest value
516
+ y[4] = np.inf
517
+ res2 = mannwhitneyu(x, y)
518
+
519
+ assert_equal(res1.statistic, res2.statistic)
520
+ assert_equal(res1.pvalue, res2.pvalue)
521
+
522
+ # NaNs should propagate by default.
523
+ y[4] = np.nan
524
+ res3 = mannwhitneyu(x, y)
525
+ assert_equal(res3.statistic, np.nan)
526
+ assert_equal(res3.pvalue, np.nan)
527
+
528
+ cases_11355 = [([1, 2, 3, 4],
529
+ [3, 6, 7, 8, np.inf, 3, 2, 1, 4, 4, 5],
530
+ 10, 0.1297704873477),
531
+ ([1, 2, 3, 4],
532
+ [3, 6, 7, 8, np.inf, np.inf, 2, 1, 4, 4, 5],
533
+ 8.5, 0.08735617507695),
534
+ ([1, 2, np.inf, 4],
535
+ [3, 6, 7, 8, np.inf, 3, 2, 1, 4, 4, 5],
536
+ 17.5, 0.5988856695752),
537
+ ([1, 2, np.inf, 4],
538
+ [3, 6, 7, 8, np.inf, np.inf, 2, 1, 4, 4, 5],
539
+ 16, 0.4687165824462),
540
+ ([1, np.inf, np.inf, 4],
541
+ [3, 6, 7, 8, np.inf, np.inf, 2, 1, 4, 4, 5],
542
+ 24.5, 0.7912517950119)]
543
+
544
+ @pytest.mark.parametrize(("x", "y", "statistic", "pvalue"), cases_11355)
545
+ def test_gh_11355b(self, x, y, statistic, pvalue):
546
+ # Test for correct behavior with NaN/Inf in input
547
+ res = mannwhitneyu(x, y, method='asymptotic')
548
+ assert_allclose(res.statistic, statistic, atol=1e-12)
549
+ assert_allclose(res.pvalue, pvalue, atol=1e-12)
550
+
551
+ cases_9184 = [[True, "less", "asymptotic", 0.900775348204],
552
+ [True, "greater", "asymptotic", 0.1223118025635],
553
+ [True, "two-sided", "asymptotic", 0.244623605127],
554
+ [False, "less", "asymptotic", 0.8896643190401],
555
+ [False, "greater", "asymptotic", 0.1103356809599],
556
+ [False, "two-sided", "asymptotic", 0.2206713619198],
557
+ [True, "less", "exact", 0.8967698967699],
558
+ [True, "greater", "exact", 0.1272061272061],
559
+ [True, "two-sided", "exact", 0.2544122544123]]
560
+
561
+ @pytest.mark.parametrize(("use_continuity", "alternative",
562
+ "method", "pvalue_exp"), cases_9184)
563
+ def test_gh_9184(self, use_continuity, alternative, method, pvalue_exp):
564
+ # gh-9184 might be considered a doc-only bug. Please see the
565
+ # documentation to confirm that mannwhitneyu correctly notes
566
+ # that the output statistic is that of the first sample (x). In any
567
+ # case, check the case provided there against output from R.
568
+ # R code:
569
+ # options(digits=16)
570
+ # x <- c(0.80, 0.83, 1.89, 1.04, 1.45, 1.38, 1.91, 1.64, 0.73, 1.46)
571
+ # y <- c(1.15, 0.88, 0.90, 0.74, 1.21)
572
+ # wilcox.test(x, y, alternative = "less", exact = FALSE)
573
+ # wilcox.test(x, y, alternative = "greater", exact = FALSE)
574
+ # wilcox.test(x, y, alternative = "two.sided", exact = FALSE)
575
+ # wilcox.test(x, y, alternative = "less", exact = FALSE,
576
+ # correct=FALSE)
577
+ # wilcox.test(x, y, alternative = "greater", exact = FALSE,
578
+ # correct=FALSE)
579
+ # wilcox.test(x, y, alternative = "two.sided", exact = FALSE,
580
+ # correct=FALSE)
581
+ # wilcox.test(x, y, alternative = "less", exact = TRUE)
582
+ # wilcox.test(x, y, alternative = "greater", exact = TRUE)
583
+ # wilcox.test(x, y, alternative = "two.sided", exact = TRUE)
584
+ statistic_exp = 35
585
+ x = (0.80, 0.83, 1.89, 1.04, 1.45, 1.38, 1.91, 1.64, 0.73, 1.46)
586
+ y = (1.15, 0.88, 0.90, 0.74, 1.21)
587
+ res = mannwhitneyu(x, y, use_continuity=use_continuity,
588
+ alternative=alternative, method=method)
589
+ assert_equal(res.statistic, statistic_exp)
590
+ assert_allclose(res.pvalue, pvalue_exp)
591
+
592
+ def test_gh_4067(self):
593
+ # Test for correct behavior with all NaN input - default is propagate
594
+ a = np.array([np.nan, np.nan, np.nan, np.nan, np.nan])
595
+ b = np.array([np.nan, np.nan, np.nan, np.nan, np.nan])
596
+ res = mannwhitneyu(a, b)
597
+ assert_equal(res.statistic, np.nan)
598
+ assert_equal(res.pvalue, np.nan)
599
+
600
+ # All cases checked against R wilcox.test, e.g.
601
+ # options(digits=16)
602
+ # x = c(1, 2, 3)
603
+ # y = c(1.5, 2.5)
604
+ # wilcox.test(x, y, exact=FALSE, alternative='less')
605
+
606
+ cases_2118 = [[[1, 2, 3], [1.5, 2.5], "greater", (3, 0.6135850036578)],
607
+ [[1, 2, 3], [1.5, 2.5], "less", (3, 0.6135850036578)],
608
+ [[1, 2, 3], [1.5, 2.5], "two-sided", (3, 1.0)],
609
+ [[1, 2, 3], [2], "greater", (1.5, 0.681324055883)],
610
+ [[1, 2, 3], [2], "less", (1.5, 0.681324055883)],
611
+ [[1, 2, 3], [2], "two-sided", (1.5, 1)],
612
+ [[1, 2], [1, 2], "greater", (2, 0.667497228949)],
613
+ [[1, 2], [1, 2], "less", (2, 0.667497228949)],
614
+ [[1, 2], [1, 2], "two-sided", (2, 1)]]
615
+
616
+ @pytest.mark.parametrize(["x", "y", "alternative", "expected"], cases_2118)
617
+ def test_gh_2118(self, x, y, alternative, expected):
618
+ # test cases in which U == m*n/2 when method is asymptotic
619
+ # applying continuity correction could result in p-value > 1
620
+ res = mannwhitneyu(x, y, use_continuity=True, alternative=alternative,
621
+ method="asymptotic")
622
+ assert_allclose(res, expected, rtol=1e-12)
623
+
624
+ def test_gh19692_smaller_table(self):
625
+ # In gh-19692, we noted that the shape of the cache used in calculating
626
+ # p-values was dependent on the order of the inputs because the sample
627
+ # sizes n1 and n2 changed. This was indicative of unnecessary cache
628
+ # growth and redundant calculation. Check that this is resolved.
629
+ rng = np.random.default_rng(7600451795963068007)
630
+ m, n = 5, 11
631
+ x = rng.random(size=m)
632
+ y = rng.random(size=n)
633
+
634
+ setattr(_mwu_state, 's', _MWU(0, 0))
635
+ _mwu_state.s.reset() # reset cache
636
+
637
+ res = stats.mannwhitneyu(x, y, method='exact')
638
+ shape = _mwu_state.s.configurations.shape
639
+ assert shape[-1] == min(res.statistic, m*n - res.statistic) + 1
640
+ stats.mannwhitneyu(y, x, method='exact')
641
+ assert shape == _mwu_state.s.configurations.shape # same with reversed sizes
642
+
643
+ # Also, we weren't exploiting the symmetry of the null distribution
644
+ # to its full potential. Ensure that the null distribution is not
645
+ # evaluated explicitly for `k > m*n/2`.
646
+ _mwu_state.s.reset() # reset cache
647
+ stats.mannwhitneyu(x, 0*y, method='exact', alternative='greater')
648
+ shape = _mwu_state.s.configurations.shape
649
+ assert shape[-1] == 1 # k is smallest possible
650
+ stats.mannwhitneyu(0*x, y, method='exact', alternative='greater')
651
+ assert shape == _mwu_state.s.configurations.shape
652
+
653
+ @pytest.mark.parametrize('alternative', ['less', 'greater', 'two-sided'])
654
+ def test_permutation_method(self, alternative):
655
+ rng = np.random.default_rng(7600451795963068007)
656
+ x = rng.random(size=(2, 5))
657
+ y = rng.random(size=(2, 6))
658
+ res = stats.mannwhitneyu(x, y, method=stats.PermutationMethod(),
659
+ alternative=alternative, axis=1)
660
+ res2 = stats.mannwhitneyu(x, y, method='exact',
661
+ alternative=alternative, axis=1)
662
+ assert_allclose(res.statistic, res2.statistic, rtol=1e-15)
663
+ assert_allclose(res.pvalue, res2.pvalue, rtol=1e-15)
664
+
665
+
666
+ class TestSomersD(_TestPythranFunc):
667
+ def setup_method(self):
668
+ self.dtypes = self.ALL_INTEGER + self.ALL_FLOAT
669
+ self.arguments = {0: (np.arange(10),
670
+ self.ALL_INTEGER + self.ALL_FLOAT),
671
+ 1: (np.arange(10),
672
+ self.ALL_INTEGER + self.ALL_FLOAT)}
673
+ input_array = [self.arguments[idx][0] for idx in self.arguments]
674
+ # In this case, self.partialfunc can simply be stats.somersd,
675
+ # since `alternative` is an optional argument. If it is required,
676
+ # we can use functools.partial to freeze the value, because
677
+ # we only mainly test various array inputs, not str, etc.
678
+ self.partialfunc = functools.partial(stats.somersd,
679
+ alternative='two-sided')
680
+ self.expected = self.partialfunc(*input_array)
681
+
682
+ def pythranfunc(self, *args):
683
+ res = self.partialfunc(*args)
684
+ assert_allclose(res.statistic, self.expected.statistic, atol=1e-15)
685
+ assert_allclose(res.pvalue, self.expected.pvalue, atol=1e-15)
686
+
687
+ def test_pythranfunc_keywords(self):
688
+ # Not specifying the optional keyword args
689
+ table = [[27, 25, 14, 7, 0], [7, 14, 18, 35, 12], [1, 3, 2, 7, 17]]
690
+ res1 = stats.somersd(table)
691
+ # Specifying the optional keyword args with default value
692
+ optional_args = self.get_optional_args(stats.somersd)
693
+ res2 = stats.somersd(table, **optional_args)
694
+ # Check if the results are the same in two cases
695
+ assert_allclose(res1.statistic, res2.statistic, atol=1e-15)
696
+ assert_allclose(res1.pvalue, res2.pvalue, atol=1e-15)
697
+
698
+ def test_like_kendalltau(self):
699
+ # All tests correspond with one in test_stats.py `test_kendalltau`
700
+
701
+ # case without ties, con-dis equal zero
702
+ x = [5, 2, 1, 3, 6, 4, 7, 8]
703
+ y = [5, 2, 6, 3, 1, 8, 7, 4]
704
+ # Cross-check with result from SAS FREQ:
705
+ expected = (0.000000000000000, 1.000000000000000)
706
+ res = stats.somersd(x, y)
707
+ assert_allclose(res.statistic, expected[0], atol=1e-15)
708
+ assert_allclose(res.pvalue, expected[1], atol=1e-15)
709
+
710
+ # case without ties, con-dis equal zero
711
+ x = [0, 5, 2, 1, 3, 6, 4, 7, 8]
712
+ y = [5, 2, 0, 6, 3, 1, 8, 7, 4]
713
+ # Cross-check with result from SAS FREQ:
714
+ expected = (0.000000000000000, 1.000000000000000)
715
+ res = stats.somersd(x, y)
716
+ assert_allclose(res.statistic, expected[0], atol=1e-15)
717
+ assert_allclose(res.pvalue, expected[1], atol=1e-15)
718
+
719
+ # case without ties, con-dis close to zero
720
+ x = [5, 2, 1, 3, 6, 4, 7]
721
+ y = [5, 2, 6, 3, 1, 7, 4]
722
+ # Cross-check with result from SAS FREQ:
723
+ expected = (-0.142857142857140, 0.630326953157670)
724
+ res = stats.somersd(x, y)
725
+ assert_allclose(res.statistic, expected[0], atol=1e-15)
726
+ assert_allclose(res.pvalue, expected[1], atol=1e-15)
727
+
728
+ # simple case without ties
729
+ x = np.arange(10)
730
+ y = np.arange(10)
731
+ # Cross-check with result from SAS FREQ:
732
+ # SAS p value is not provided.
733
+ expected = (1.000000000000000, 0)
734
+ res = stats.somersd(x, y)
735
+ assert_allclose(res.statistic, expected[0], atol=1e-15)
736
+ assert_allclose(res.pvalue, expected[1], atol=1e-15)
737
+
738
+ # swap a couple values and a couple more
739
+ x = np.arange(10)
740
+ y = np.array([0, 2, 1, 3, 4, 6, 5, 7, 8, 9])
741
+ # Cross-check with result from SAS FREQ:
742
+ expected = (0.911111111111110, 0.000000000000000)
743
+ res = stats.somersd(x, y)
744
+ assert_allclose(res.statistic, expected[0], atol=1e-15)
745
+ assert_allclose(res.pvalue, expected[1], atol=1e-15)
746
+
747
+ # same in opposite direction
748
+ x = np.arange(10)
749
+ y = np.arange(10)[::-1]
750
+ # Cross-check with result from SAS FREQ:
751
+ # SAS p value is not provided.
752
+ expected = (-1.000000000000000, 0)
753
+ res = stats.somersd(x, y)
754
+ assert_allclose(res.statistic, expected[0], atol=1e-15)
755
+ assert_allclose(res.pvalue, expected[1], atol=1e-15)
756
+
757
+ # swap a couple values and a couple more
758
+ x = np.arange(10)
759
+ y = np.array([9, 7, 8, 6, 5, 3, 4, 2, 1, 0])
760
+ # Cross-check with result from SAS FREQ:
761
+ expected = (-0.9111111111111111, 0.000000000000000)
762
+ res = stats.somersd(x, y)
763
+ assert_allclose(res.statistic, expected[0], atol=1e-15)
764
+ assert_allclose(res.pvalue, expected[1], atol=1e-15)
765
+
766
+ # with some ties
767
+ x1 = [12, 2, 1, 12, 2]
768
+ x2 = [1, 4, 7, 1, 0]
769
+ # Cross-check with result from SAS FREQ:
770
+ expected = (-0.500000000000000, 0.304901788178780)
771
+ res = stats.somersd(x1, x2)
772
+ assert_allclose(res.statistic, expected[0], atol=1e-15)
773
+ assert_allclose(res.pvalue, expected[1], atol=1e-15)
774
+
775
+ # with only ties in one or both inputs
776
+ # SAS will not produce an output for these:
777
+ # NOTE: No statistics are computed for x * y because x has fewer
778
+ # than 2 nonmissing levels.
779
+ # WARNING: No OUTPUT data set is produced for this table because a
780
+ # row or column variable has fewer than 2 nonmissing levels and no
781
+ # statistics are computed.
782
+
783
+ res = stats.somersd([2, 2, 2], [2, 2, 2])
784
+ assert_allclose(res.statistic, np.nan)
785
+ assert_allclose(res.pvalue, np.nan)
786
+
787
+ res = stats.somersd([2, 0, 2], [2, 2, 2])
788
+ assert_allclose(res.statistic, np.nan)
789
+ assert_allclose(res.pvalue, np.nan)
790
+
791
+ res = stats.somersd([2, 2, 2], [2, 0, 2])
792
+ assert_allclose(res.statistic, np.nan)
793
+ assert_allclose(res.pvalue, np.nan)
794
+
795
+ res = stats.somersd([0], [0])
796
+ assert_allclose(res.statistic, np.nan)
797
+ assert_allclose(res.pvalue, np.nan)
798
+
799
+ # empty arrays provided as input
800
+ res = stats.somersd([], [])
801
+ assert_allclose(res.statistic, np.nan)
802
+ assert_allclose(res.pvalue, np.nan)
803
+
804
+ # test unequal length inputs
805
+ x = np.arange(10.)
806
+ y = np.arange(20.)
807
+ assert_raises(ValueError, stats.somersd, x, y)
808
+
809
+ def test_asymmetry(self):
810
+ # test that somersd is asymmetric w.r.t. input order and that
811
+ # convention is as described: first input is row variable & independent
812
+ # data is from Wikipedia:
813
+ # https://en.wikipedia.org/wiki/Somers%27_D
814
+ # but currently that example contradicts itself - it says X is
815
+ # independent yet take D_XY
816
+
817
+ x = [1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 1, 2,
818
+ 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3]
819
+ y = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
820
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
821
+ # Cross-check with result from SAS FREQ:
822
+ d_cr = 0.272727272727270
823
+ d_rc = 0.342857142857140
824
+ p = 0.092891940883700 # same p-value for either direction
825
+ res = stats.somersd(x, y)
826
+ assert_allclose(res.statistic, d_cr, atol=1e-15)
827
+ assert_allclose(res.pvalue, p, atol=1e-4)
828
+ assert_equal(res.table.shape, (3, 2))
829
+ res = stats.somersd(y, x)
830
+ assert_allclose(res.statistic, d_rc, atol=1e-15)
831
+ assert_allclose(res.pvalue, p, atol=1e-15)
832
+ assert_equal(res.table.shape, (2, 3))
833
+
834
+ def test_somers_original(self):
835
+ # test against Somers' original paper [1]
836
+
837
+ # Table 5A
838
+ # Somers' convention was column IV
839
+ table = np.array([[8, 2], [6, 5], [3, 4], [1, 3], [2, 3]])
840
+ # Our convention (and that of SAS FREQ) is row IV
841
+ table = table.T
842
+ dyx = 129/340
843
+ assert_allclose(stats.somersd(table).statistic, dyx)
844
+
845
+ # table 7A - d_yx = 1
846
+ table = np.array([[25, 0], [85, 0], [0, 30]])
847
+ dxy, dyx = 3300/5425, 3300/3300
848
+ assert_allclose(stats.somersd(table).statistic, dxy)
849
+ assert_allclose(stats.somersd(table.T).statistic, dyx)
850
+
851
+ # table 7B - d_yx < 0
852
+ table = np.array([[25, 0], [0, 30], [85, 0]])
853
+ dyx = -1800/3300
854
+ assert_allclose(stats.somersd(table.T).statistic, dyx)
855
+
856
+ def test_contingency_table_with_zero_rows_cols(self):
857
+ # test that zero rows/cols in contingency table don't affect result
858
+
859
+ N = 100
860
+ shape = 4, 6
861
+ size = np.prod(shape)
862
+
863
+ rng = np.random.RandomState(0)
864
+ s = stats.multinomial.rvs(N, p=np.ones(size)/size,
865
+ random_state=rng).reshape(shape)
866
+ res = stats.somersd(s)
867
+
868
+ s2 = np.insert(s, 2, np.zeros(shape[1]), axis=0)
869
+ res2 = stats.somersd(s2)
870
+
871
+ s3 = np.insert(s, 2, np.zeros(shape[0]), axis=1)
872
+ res3 = stats.somersd(s3)
873
+
874
+ s4 = np.insert(s2, 2, np.zeros(shape[0]+1), axis=1)
875
+ res4 = stats.somersd(s4)
876
+
877
+ # Cross-check with result from SAS FREQ:
878
+ assert_allclose(res.statistic, -0.116981132075470, atol=1e-15)
879
+ assert_allclose(res.statistic, res2.statistic)
880
+ assert_allclose(res.statistic, res3.statistic)
881
+ assert_allclose(res.statistic, res4.statistic)
882
+
883
+ assert_allclose(res.pvalue, 0.156376448188150, atol=1e-15)
884
+ assert_allclose(res.pvalue, res2.pvalue)
885
+ assert_allclose(res.pvalue, res3.pvalue)
886
+ assert_allclose(res.pvalue, res4.pvalue)
887
+
888
+ def test_invalid_contingency_tables(self):
889
+ N = 100
890
+ shape = 4, 6
891
+ size = np.prod(shape)
892
+
893
+ rng = np.random.default_rng(0)
894
+ # start with a valid contingency table
895
+ s = stats.multinomial.rvs(N, p=np.ones(size)/size,
896
+ random_state=rng).reshape(shape)
897
+
898
+ s5 = s - 2
899
+ message = "All elements of the contingency table must be non-negative"
900
+ with assert_raises(ValueError, match=message):
901
+ stats.somersd(s5)
902
+
903
+ s6 = s + 0.01
904
+ message = "All elements of the contingency table must be integer"
905
+ with assert_raises(ValueError, match=message):
906
+ stats.somersd(s6)
907
+
908
+ message = ("At least two elements of the contingency "
909
+ "table must be nonzero.")
910
+ with assert_raises(ValueError, match=message):
911
+ stats.somersd([[]])
912
+
913
+ with assert_raises(ValueError, match=message):
914
+ stats.somersd([[1]])
915
+
916
+ s7 = np.zeros((3, 3))
917
+ with assert_raises(ValueError, match=message):
918
+ stats.somersd(s7)
919
+
920
+ s7[0, 1] = 1
921
+ with assert_raises(ValueError, match=message):
922
+ stats.somersd(s7)
923
+
924
+ def test_only_ranks_matter(self):
925
+ # only ranks of input data should matter
926
+ x = [1, 2, 3]
927
+ x2 = [-1, 2.1, np.inf]
928
+ y = [3, 2, 1]
929
+ y2 = [0, -0.5, -np.inf]
930
+ res = stats.somersd(x, y)
931
+ res2 = stats.somersd(x2, y2)
932
+ assert_equal(res.statistic, res2.statistic)
933
+ assert_equal(res.pvalue, res2.pvalue)
934
+
935
+ def test_contingency_table_return(self):
936
+ # check that contingency table is returned
937
+ x = np.arange(10)
938
+ y = np.arange(10)
939
+ res = stats.somersd(x, y)
940
+ assert_equal(res.table, np.eye(10))
941
+
942
+ def test_somersd_alternative(self):
943
+ # Test alternative parameter, asymptotic method (due to tie)
944
+
945
+ # Based on scipy.stats.test_stats.TestCorrSpearman2::test_alternative
946
+ x1 = [1, 2, 3, 4, 5]
947
+ x2 = [5, 6, 7, 8, 7]
948
+
949
+ # strong positive correlation
950
+ expected = stats.somersd(x1, x2, alternative="two-sided")
951
+ assert expected.statistic > 0
952
+
953
+ # rank correlation > 0 -> large "less" p-value
954
+ res = stats.somersd(x1, x2, alternative="less")
955
+ assert_equal(res.statistic, expected.statistic)
956
+ assert_allclose(res.pvalue, 1 - (expected.pvalue / 2))
957
+
958
+ # rank correlation > 0 -> small "greater" p-value
959
+ res = stats.somersd(x1, x2, alternative="greater")
960
+ assert_equal(res.statistic, expected.statistic)
961
+ assert_allclose(res.pvalue, expected.pvalue / 2)
962
+
963
+ # reverse the direction of rank correlation
964
+ x2.reverse()
965
+
966
+ # strong negative correlation
967
+ expected = stats.somersd(x1, x2, alternative="two-sided")
968
+ assert expected.statistic < 0
969
+
970
+ # rank correlation < 0 -> large "greater" p-value
971
+ res = stats.somersd(x1, x2, alternative="greater")
972
+ assert_equal(res.statistic, expected.statistic)
973
+ assert_allclose(res.pvalue, 1 - (expected.pvalue / 2))
974
+
975
+ # rank correlation < 0 -> small "less" p-value
976
+ res = stats.somersd(x1, x2, alternative="less")
977
+ assert_equal(res.statistic, expected.statistic)
978
+ assert_allclose(res.pvalue, expected.pvalue / 2)
979
+
980
+ with pytest.raises(ValueError, match="`alternative` must be..."):
981
+ stats.somersd(x1, x2, alternative="ekki-ekki")
982
+
983
+ @pytest.mark.parametrize("positive_correlation", (False, True))
984
+ def test_somersd_perfect_correlation(self, positive_correlation):
985
+ # Before the addition of `alternative`, perfect correlation was
986
+ # treated as a special case. Now it is treated like any other case, but
987
+ # make sure there are no divide by zero warnings or associated errors
988
+
989
+ x1 = np.arange(10)
990
+ x2 = x1 if positive_correlation else np.flip(x1)
991
+ expected_statistic = 1 if positive_correlation else -1
992
+
993
+ # perfect correlation -> small "two-sided" p-value (0)
994
+ res = stats.somersd(x1, x2, alternative="two-sided")
995
+ assert res.statistic == expected_statistic
996
+ assert res.pvalue == 0
997
+
998
+ # rank correlation > 0 -> large "less" p-value (1)
999
+ res = stats.somersd(x1, x2, alternative="less")
1000
+ assert res.statistic == expected_statistic
1001
+ assert res.pvalue == (1 if positive_correlation else 0)
1002
+
1003
+ # rank correlation > 0 -> small "greater" p-value (0)
1004
+ res = stats.somersd(x1, x2, alternative="greater")
1005
+ assert res.statistic == expected_statistic
1006
+ assert res.pvalue == (0 if positive_correlation else 1)
1007
+
1008
+ @pytest.mark.thread_unsafe
1009
+ def test_somersd_large_inputs_gh18132(self):
1010
+ # Test that large inputs where potential overflows could occur give
1011
+ # the expected output. This is tested in the case of binary inputs.
1012
+ # See gh-18126.
1013
+
1014
+ # generate lists of random classes 1-2 (binary)
1015
+ classes = [1, 2]
1016
+ n_samples = 10 ** 6
1017
+ random.seed(6272161)
1018
+ x = random.choices(classes, k=n_samples)
1019
+ y = random.choices(classes, k=n_samples)
1020
+
1021
+ # get value to compare with: sklearn output
1022
+ # from sklearn import metrics
1023
+ # val_auc_sklearn = metrics.roc_auc_score(x, y)
1024
+ # # convert to the Gini coefficient (Gini = (AUC*2)-1)
1025
+ # val_sklearn = 2 * val_auc_sklearn - 1
1026
+ val_sklearn = -0.001528138777036947
1027
+
1028
+ # calculate the Somers' D statistic, which should be equal to the
1029
+ # result of val_sklearn until approximately machine precision
1030
+ val_scipy = stats.somersd(x, y).statistic
1031
+ assert_allclose(val_sklearn, val_scipy, atol=1e-15)
1032
+
1033
+
1034
+ class TestBarnardExact:
1035
+ """Some tests to show that barnard_exact() works correctly."""
1036
+
1037
+ @pytest.mark.parametrize(
1038
+ "input_sample,expected",
1039
+ [
1040
+ ([[43, 40], [10, 39]], (3.555406779643, 0.000362832367)),
1041
+ ([[100, 2], [1000, 5]], (-1.776382925679, 0.135126970878)),
1042
+ ([[2, 7], [8, 2]], (-2.518474945157, 0.019210815430)),
1043
+ ([[5, 1], [10, 10]], (1.449486150679, 0.156277546306)),
1044
+ ([[5, 15], [20, 20]], (-1.851640199545, 0.066363501421)),
1045
+ ([[5, 16], [20, 25]], (-1.609639949352, 0.116984852192)),
1046
+ ([[10, 5], [10, 1]], (-1.449486150679, 0.177536588915)),
1047
+ ([[5, 0], [1, 4]], (2.581988897472, 0.013671875000)),
1048
+ ([[0, 1], [3, 2]], (-1.095445115010, 0.509667991877)),
1049
+ ([[0, 2], [6, 4]], (-1.549193338483, 0.197019618792)),
1050
+ ([[2, 7], [8, 2]], (-2.518474945157, 0.019210815430)),
1051
+ ],
1052
+ )
1053
+ def test_precise(self, input_sample, expected):
1054
+ """The expected values have been generated by R, using a resolution
1055
+ for the nuisance parameter of 1e-6 :
1056
+ ```R
1057
+ library(Barnard)
1058
+ options(digits=10)
1059
+ barnard.test(43, 40, 10, 39, dp=1e-6, pooled=TRUE)
1060
+ ```
1061
+ """
1062
+ res = barnard_exact(input_sample)
1063
+ statistic, pvalue = res.statistic, res.pvalue
1064
+ assert_allclose([statistic, pvalue], expected)
1065
+
1066
+ @pytest.mark.parametrize(
1067
+ "input_sample,expected",
1068
+ [
1069
+ ([[43, 40], [10, 39]], (3.920362887717, 0.000289470662)),
1070
+ ([[100, 2], [1000, 5]], (-1.139432816087, 0.950272080594)),
1071
+ ([[2, 7], [8, 2]], (-3.079373904042, 0.020172119141)),
1072
+ ([[5, 1], [10, 10]], (1.622375939458, 0.150599922226)),
1073
+ ([[5, 15], [20, 20]], (-1.974771239528, 0.063038448651)),
1074
+ ([[5, 16], [20, 25]], (-1.722122973346, 0.133329494287)),
1075
+ ([[10, 5], [10, 1]], (-1.765469659009, 0.250566655215)),
1076
+ ([[5, 0], [1, 4]], (5.477225575052, 0.007812500000)),
1077
+ ([[0, 1], [3, 2]], (-1.224744871392, 0.509667991877)),
1078
+ ([[0, 2], [6, 4]], (-1.732050807569, 0.197019618792)),
1079
+ ([[2, 7], [8, 2]], (-3.079373904042, 0.020172119141)),
1080
+ ],
1081
+ )
1082
+ def test_pooled_param(self, input_sample, expected):
1083
+ """The expected values have been generated by R, using a resolution
1084
+ for the nuisance parameter of 1e-6 :
1085
+ ```R
1086
+ library(Barnard)
1087
+ options(digits=10)
1088
+ barnard.test(43, 40, 10, 39, dp=1e-6, pooled=FALSE)
1089
+ ```
1090
+ """
1091
+ res = barnard_exact(input_sample, pooled=False)
1092
+ statistic, pvalue = res.statistic, res.pvalue
1093
+ assert_allclose([statistic, pvalue], expected)
1094
+
1095
+ def test_raises(self):
1096
+ # test we raise an error for wrong input number of nuisances.
1097
+ error_msg = (
1098
+ "Number of points `n` must be strictly positive, found 0"
1099
+ )
1100
+ with assert_raises(ValueError, match=error_msg):
1101
+ barnard_exact([[1, 2], [3, 4]], n=0)
1102
+
1103
+ # test we raise an error for wrong shape of input.
1104
+ error_msg = "The input `table` must be of shape \\(2, 2\\)."
1105
+ with assert_raises(ValueError, match=error_msg):
1106
+ barnard_exact(np.arange(6).reshape(2, 3))
1107
+
1108
+ # Test all values must be positives
1109
+ error_msg = "All values in `table` must be nonnegative."
1110
+ with assert_raises(ValueError, match=error_msg):
1111
+ barnard_exact([[-1, 2], [3, 4]])
1112
+
1113
+ # Test value error on wrong alternative param
1114
+ error_msg = (
1115
+ "`alternative` should be one of {'two-sided', 'less', 'greater'},"
1116
+ " found .*"
1117
+ )
1118
+ with assert_raises(ValueError, match=error_msg):
1119
+ barnard_exact([[1, 2], [3, 4]], "not-correct")
1120
+
1121
+ @pytest.mark.parametrize(
1122
+ "input_sample,expected",
1123
+ [
1124
+ ([[0, 0], [4, 3]], (1.0, 0)),
1125
+ ],
1126
+ )
1127
+ def test_edge_cases(self, input_sample, expected):
1128
+ res = barnard_exact(input_sample)
1129
+ statistic, pvalue = res.statistic, res.pvalue
1130
+ assert_equal(pvalue, expected[0])
1131
+ assert_equal(statistic, expected[1])
1132
+
1133
+ @pytest.mark.parametrize(
1134
+ "input_sample,expected",
1135
+ [
1136
+ ([[0, 5], [0, 10]], (1.0, np.nan)),
1137
+ ([[5, 0], [10, 0]], (1.0, np.nan)),
1138
+ ],
1139
+ )
1140
+ def test_row_or_col_zero(self, input_sample, expected):
1141
+ res = barnard_exact(input_sample)
1142
+ statistic, pvalue = res.statistic, res.pvalue
1143
+ assert_equal(pvalue, expected[0])
1144
+ assert_equal(statistic, expected[1])
1145
+
1146
+ @pytest.mark.parametrize(
1147
+ "input_sample,expected",
1148
+ [
1149
+ ([[2, 7], [8, 2]], (-2.518474945157, 0.009886140845)),
1150
+ ([[7, 200], [300, 8]], (-21.320036698460, 0.0)),
1151
+ ([[21, 28], [1957, 6]], (-30.489638143953, 0.0)),
1152
+ ],
1153
+ )
1154
+ @pytest.mark.parametrize("alternative", ["greater", "less"])
1155
+ def test_less_greater(self, input_sample, expected, alternative):
1156
+ """
1157
+ "The expected values have been generated by R, using a resolution
1158
+ for the nuisance parameter of 1e-6 :
1159
+ ```R
1160
+ library(Barnard)
1161
+ options(digits=10)
1162
+ a = barnard.test(2, 7, 8, 2, dp=1e-6, pooled=TRUE)
1163
+ a$p.value[1]
1164
+ ```
1165
+ In this test, we are using the "one-sided" return value `a$p.value[1]`
1166
+ to test our pvalue.
1167
+ """
1168
+ expected_stat, less_pvalue_expect = expected
1169
+
1170
+ if alternative == "greater":
1171
+ input_sample = np.array(input_sample)[:, ::-1]
1172
+ expected_stat = -expected_stat
1173
+
1174
+ res = barnard_exact(input_sample, alternative=alternative)
1175
+ statistic, pvalue = res.statistic, res.pvalue
1176
+ assert_allclose(
1177
+ [statistic, pvalue], [expected_stat, less_pvalue_expect], atol=1e-7
1178
+ )
1179
+
1180
+
1181
+ class TestBoschlooExact:
1182
+ """Some tests to show that boschloo_exact() works correctly."""
1183
+
1184
+ ATOL = 1e-7
1185
+
1186
+ @pytest.mark.parametrize(
1187
+ "input_sample,expected",
1188
+ [
1189
+ ([[2, 7], [8, 2]], (0.01852173, 0.009886142)),
1190
+ ([[5, 1], [10, 10]], (0.9782609, 0.9450994)),
1191
+ ([[5, 16], [20, 25]], (0.08913823, 0.05827348)),
1192
+ ([[10, 5], [10, 1]], (0.1652174, 0.08565611)),
1193
+ ([[5, 0], [1, 4]], (1, 1)),
1194
+ ([[0, 1], [3, 2]], (0.5, 0.34375)),
1195
+ ([[2, 7], [8, 2]], (0.01852173, 0.009886142)),
1196
+ ([[7, 12], [8, 3]], (0.06406797, 0.03410916)),
1197
+ ([[10, 24], [25, 37]], (0.2009359, 0.1512882)),
1198
+ ],
1199
+ )
1200
+ def test_less(self, input_sample, expected):
1201
+ """The expected values have been generated by R, using a resolution
1202
+ for the nuisance parameter of 1e-8 :
1203
+ ```R
1204
+ library(Exact)
1205
+ options(digits=10)
1206
+ data <- matrix(c(43, 10, 40, 39), 2, 2, byrow=TRUE)
1207
+ a = exact.test(data, method="Boschloo", alternative="less",
1208
+ tsmethod="central", np.interval=TRUE, beta=1e-8)
1209
+ ```
1210
+ """
1211
+ res = boschloo_exact(input_sample, alternative="less")
1212
+ statistic, pvalue = res.statistic, res.pvalue
1213
+ assert_allclose([statistic, pvalue], expected, atol=self.ATOL)
1214
+
1215
+ @pytest.mark.parametrize(
1216
+ "input_sample,expected",
1217
+ [
1218
+ ([[43, 40], [10, 39]], (0.0002875544, 0.0001615562)),
1219
+ ([[2, 7], [8, 2]], (0.9990149, 0.9918327)),
1220
+ ([[5, 1], [10, 10]], (0.1652174, 0.09008534)),
1221
+ ([[5, 15], [20, 20]], (0.9849087, 0.9706997)),
1222
+ ([[5, 16], [20, 25]], (0.972349, 0.9524124)),
1223
+ ([[5, 0], [1, 4]], (0.02380952, 0.006865367)),
1224
+ ([[0, 1], [3, 2]], (1, 1)),
1225
+ ([[0, 2], [6, 4]], (1, 1)),
1226
+ ([[2, 7], [8, 2]], (0.9990149, 0.9918327)),
1227
+ ([[7, 12], [8, 3]], (0.9895302, 0.9771215)),
1228
+ ([[10, 24], [25, 37]], (0.9012936, 0.8633275)),
1229
+ ],
1230
+ )
1231
+ def test_greater(self, input_sample, expected):
1232
+ """The expected values have been generated by R, using a resolution
1233
+ for the nuisance parameter of 1e-8 :
1234
+ ```R
1235
+ library(Exact)
1236
+ options(digits=10)
1237
+ data <- matrix(c(43, 10, 40, 39), 2, 2, byrow=TRUE)
1238
+ a = exact.test(data, method="Boschloo", alternative="greater",
1239
+ tsmethod="central", np.interval=TRUE, beta=1e-8)
1240
+ ```
1241
+ """
1242
+ res = boschloo_exact(input_sample, alternative="greater")
1243
+ statistic, pvalue = res.statistic, res.pvalue
1244
+ assert_allclose([statistic, pvalue], expected, atol=self.ATOL)
1245
+
1246
+ @pytest.mark.parametrize(
1247
+ "input_sample,expected",
1248
+ [
1249
+ ([[43, 40], [10, 39]], (0.0002875544, 0.0003231115)),
1250
+ ([[2, 7], [8, 2]], (0.01852173, 0.01977228)),
1251
+ ([[5, 1], [10, 10]], (0.1652174, 0.1801707)),
1252
+ ([[5, 16], [20, 25]], (0.08913823, 0.116547)),
1253
+ ([[5, 0], [1, 4]], (0.02380952, 0.01373073)),
1254
+ ([[0, 1], [3, 2]], (0.5, 0.6875)),
1255
+ ([[2, 7], [8, 2]], (0.01852173, 0.01977228)),
1256
+ ([[7, 12], [8, 3]], (0.06406797, 0.06821831)),
1257
+ ],
1258
+ )
1259
+ def test_two_sided(self, input_sample, expected):
1260
+ """The expected values have been generated by R, using a resolution
1261
+ for the nuisance parameter of 1e-8 :
1262
+ ```R
1263
+ library(Exact)
1264
+ options(digits=10)
1265
+ data <- matrix(c(43, 10, 40, 39), 2, 2, byrow=TRUE)
1266
+ a = exact.test(data, method="Boschloo", alternative="two.sided",
1267
+ tsmethod="central", np.interval=TRUE, beta=1e-8)
1268
+ ```
1269
+ """
1270
+ res = boschloo_exact(input_sample, alternative="two-sided", n=64)
1271
+ # Need n = 64 for python 32-bit
1272
+ statistic, pvalue = res.statistic, res.pvalue
1273
+ assert_allclose([statistic, pvalue], expected, atol=self.ATOL)
1274
+
1275
+ def test_raises(self):
1276
+ # test we raise an error for wrong input number of nuisances.
1277
+ error_msg = (
1278
+ "Number of points `n` must be strictly positive, found 0"
1279
+ )
1280
+ with assert_raises(ValueError, match=error_msg):
1281
+ boschloo_exact([[1, 2], [3, 4]], n=0)
1282
+
1283
+ # test we raise an error for wrong shape of input.
1284
+ error_msg = "The input `table` must be of shape \\(2, 2\\)."
1285
+ with assert_raises(ValueError, match=error_msg):
1286
+ boschloo_exact(np.arange(6).reshape(2, 3))
1287
+
1288
+ # Test all values must be positives
1289
+ error_msg = "All values in `table` must be nonnegative."
1290
+ with assert_raises(ValueError, match=error_msg):
1291
+ boschloo_exact([[-1, 2], [3, 4]])
1292
+
1293
+ # Test value error on wrong alternative param
1294
+ error_msg = (
1295
+ r"`alternative` should be one of \('two-sided', 'less', "
1296
+ r"'greater'\), found .*"
1297
+ )
1298
+ with assert_raises(ValueError, match=error_msg):
1299
+ boschloo_exact([[1, 2], [3, 4]], "not-correct")
1300
+
1301
+ @pytest.mark.parametrize(
1302
+ "input_sample,expected",
1303
+ [
1304
+ ([[0, 5], [0, 10]], (np.nan, np.nan)),
1305
+ ([[5, 0], [10, 0]], (np.nan, np.nan)),
1306
+ ],
1307
+ )
1308
+ def test_row_or_col_zero(self, input_sample, expected):
1309
+ res = boschloo_exact(input_sample)
1310
+ statistic, pvalue = res.statistic, res.pvalue
1311
+ assert_equal(pvalue, expected[0])
1312
+ assert_equal(statistic, expected[1])
1313
+
1314
+ def test_two_sided_gt_1(self):
1315
+ # Check that returned p-value does not exceed 1 even when twice
1316
+ # the minimum of the one-sided p-values does. See gh-15345.
1317
+ tbl = [[1, 1], [13, 12]]
1318
+ pl = boschloo_exact(tbl, alternative='less').pvalue
1319
+ pg = boschloo_exact(tbl, alternative='greater').pvalue
1320
+ assert 2*min(pl, pg) > 1
1321
+ pt = boschloo_exact(tbl, alternative='two-sided').pvalue
1322
+ assert pt == 1.0
1323
+
1324
+ @pytest.mark.parametrize("alternative", ("less", "greater"))
1325
+ def test_against_fisher_exact(self, alternative):
1326
+ # Check that the statistic of `boschloo_exact` is the same as the
1327
+ # p-value of `fisher_exact` (for one-sided tests). See gh-15345.
1328
+ tbl = [[2, 7], [8, 2]]
1329
+ boschloo_stat = boschloo_exact(tbl, alternative=alternative).statistic
1330
+ fisher_p = stats.fisher_exact(tbl, alternative=alternative)[1]
1331
+ assert_allclose(boschloo_stat, fisher_p)
1332
+
1333
+
1334
+ class TestCvm_2samp:
1335
+ @pytest.mark.parametrize('args', [([], np.arange(5)),
1336
+ (np.arange(5), [1])])
1337
+ def test_too_small_input(self, args):
1338
+ with pytest.warns(SmallSampleWarning, match=too_small_1d_not_omit):
1339
+ res = cramervonmises_2samp(*args)
1340
+ assert_equal(res.statistic, np.nan)
1341
+ assert_equal(res.pvalue, np.nan)
1342
+
1343
+ def test_invalid_input(self):
1344
+ y = np.arange(5)
1345
+ msg = 'method must be either auto, exact or asymptotic'
1346
+ with pytest.raises(ValueError, match=msg):
1347
+ cramervonmises_2samp(y, y, 'xyz')
1348
+
1349
+ def test_list_input(self):
1350
+ x = [2, 3, 4, 7, 6]
1351
+ y = [0.2, 0.7, 12, 18]
1352
+ r1 = cramervonmises_2samp(x, y)
1353
+ r2 = cramervonmises_2samp(np.array(x), np.array(y))
1354
+ assert_equal((r1.statistic, r1.pvalue), (r2.statistic, r2.pvalue))
1355
+
1356
+ def test_example_conover(self):
1357
+ # Example 2 in Section 6.2 of W.J. Conover: Practical Nonparametric
1358
+ # Statistics, 1971.
1359
+ x = [7.6, 8.4, 8.6, 8.7, 9.3, 9.9, 10.1, 10.6, 11.2]
1360
+ y = [5.2, 5.7, 5.9, 6.5, 6.8, 8.2, 9.1, 9.8, 10.8, 11.3, 11.5, 12.3,
1361
+ 12.5, 13.4, 14.6]
1362
+ r = cramervonmises_2samp(x, y)
1363
+ assert_allclose(r.statistic, 0.262, atol=1e-3)
1364
+ assert_allclose(r.pvalue, 0.18, atol=1e-2)
1365
+
1366
+ @pytest.mark.parametrize('statistic, m, n, pval',
1367
+ [(710, 5, 6, 48./462),
1368
+ (1897, 7, 7, 117./1716),
1369
+ (576, 4, 6, 2./210),
1370
+ (1764, 6, 7, 2./1716)])
1371
+ def test_exact_pvalue(self, statistic, m, n, pval):
1372
+ # the exact values are taken from Anderson: On the distribution of the
1373
+ # two-sample Cramer-von-Mises criterion, 1962.
1374
+ # The values are taken from Table 2, 3, 4 and 5
1375
+ assert_equal(_pval_cvm_2samp_exact(statistic, m, n), pval)
1376
+
1377
+ @pytest.mark.xslow
1378
+ def test_large_sample(self):
1379
+ # for large samples, the statistic U gets very large
1380
+ # do a sanity check that p-value is not 0, 1 or nan
1381
+ rng = np.random.default_rng(4367)
1382
+ x = distributions.norm.rvs(size=1000000, random_state=rng)
1383
+ y = distributions.norm.rvs(size=900000, random_state=rng)
1384
+ r = cramervonmises_2samp(x, y)
1385
+ assert_(0 < r.pvalue < 1)
1386
+ r = cramervonmises_2samp(x, y+0.1)
1387
+ assert_(0 < r.pvalue < 1)
1388
+
1389
+ def test_exact_vs_asymptotic(self):
1390
+ rng = np.random.RandomState(0)
1391
+ x = rng.rand(7)
1392
+ y = rng.rand(8)
1393
+ r1 = cramervonmises_2samp(x, y, method='exact')
1394
+ r2 = cramervonmises_2samp(x, y, method='asymptotic')
1395
+ assert_equal(r1.statistic, r2.statistic)
1396
+ assert_allclose(r1.pvalue, r2.pvalue, atol=1e-2)
1397
+
1398
+ def test_method_auto(self):
1399
+ x = np.arange(20)
1400
+ y = [0.5, 4.7, 13.1]
1401
+ r1 = cramervonmises_2samp(x, y, method='exact')
1402
+ r2 = cramervonmises_2samp(x, y, method='auto')
1403
+ assert_equal(r1.pvalue, r2.pvalue)
1404
+ # switch to asymptotic if one sample has more than 20 observations
1405
+ x = np.arange(21)
1406
+ r1 = cramervonmises_2samp(x, y, method='asymptotic')
1407
+ r2 = cramervonmises_2samp(x, y, method='auto')
1408
+ assert_equal(r1.pvalue, r2.pvalue)
1409
+
1410
+ def test_same_input(self):
1411
+ # make sure trivial edge case can be handled
1412
+ # note that _cdf_cvm_inf(0) = nan. implementation avoids nan by
1413
+ # returning pvalue=1 for very small values of the statistic
1414
+ x = np.arange(15)
1415
+ res = cramervonmises_2samp(x, x)
1416
+ assert_equal((res.statistic, res.pvalue), (0.0, 1.0))
1417
+ # check exact p-value
1418
+ res = cramervonmises_2samp(x[:4], x[:4])
1419
+ assert_equal((res.statistic, res.pvalue), (0.0, 1.0))
1420
+
1421
+
1422
+ class TestTukeyHSD:
1423
+
1424
+ data_same_size = ([24.5, 23.5, 26.4, 27.1, 29.9],
1425
+ [28.4, 34.2, 29.5, 32.2, 30.1],
1426
+ [26.1, 28.3, 24.3, 26.2, 27.8])
1427
+ data_diff_size = ([24.5, 23.5, 26.28, 26.4, 27.1, 29.9, 30.1, 30.1],
1428
+ [28.4, 34.2, 29.5, 32.2, 30.1],
1429
+ [26.1, 28.3, 24.3, 26.2, 27.8])
1430
+ extreme_size = ([24.5, 23.5, 26.4],
1431
+ [28.4, 34.2, 29.5, 32.2, 30.1, 28.4, 34.2, 29.5, 32.2,
1432
+ 30.1],
1433
+ [26.1, 28.3, 24.3, 26.2, 27.8])
1434
+
1435
+ sas_same_size = """
1436
+ Comparison LowerCL Difference UpperCL Significance
1437
+ 2 - 3 0.6908830568 4.34 7.989116943 1
1438
+ 2 - 1 0.9508830568 4.6 8.249116943 1
1439
+ 3 - 2 -7.989116943 -4.34 -0.6908830568 1
1440
+ 3 - 1 -3.389116943 0.26 3.909116943 0
1441
+ 1 - 2 -8.249116943 -4.6 -0.9508830568 1
1442
+ 1 - 3 -3.909116943 -0.26 3.389116943 0
1443
+ """
1444
+
1445
+ sas_diff_size = """
1446
+ Comparison LowerCL Difference UpperCL Significance
1447
+ 2 - 1 0.2679292645 3.645 7.022070736 1
1448
+ 2 - 3 0.5934764007 4.34 8.086523599 1
1449
+ 1 - 2 -7.022070736 -3.645 -0.2679292645 1
1450
+ 1 - 3 -2.682070736 0.695 4.072070736 0
1451
+ 3 - 2 -8.086523599 -4.34 -0.5934764007 1
1452
+ 3 - 1 -4.072070736 -0.695 2.682070736 0
1453
+ """
1454
+
1455
+ sas_extreme = """
1456
+ Comparison LowerCL Difference UpperCL Significance
1457
+ 2 - 3 1.561605075 4.34 7.118394925 1
1458
+ 2 - 1 2.740784879 6.08 9.419215121 1
1459
+ 3 - 2 -7.118394925 -4.34 -1.561605075 1
1460
+ 3 - 1 -1.964526566 1.74 5.444526566 0
1461
+ 1 - 2 -9.419215121 -6.08 -2.740784879 1
1462
+ 1 - 3 -5.444526566 -1.74 1.964526566 0
1463
+ """
1464
+
1465
+ @pytest.mark.parametrize("data,res_expect_str,atol",
1466
+ ((data_same_size, sas_same_size, 1e-4),
1467
+ (data_diff_size, sas_diff_size, 1e-4),
1468
+ (extreme_size, sas_extreme, 1e-10),
1469
+ ),
1470
+ ids=["equal size sample",
1471
+ "unequal sample size",
1472
+ "extreme sample size differences"])
1473
+ def test_compare_sas(self, data, res_expect_str, atol):
1474
+ '''
1475
+ SAS code used to generate results for each sample:
1476
+ DATA ACHE;
1477
+ INPUT BRAND RELIEF;
1478
+ CARDS;
1479
+ 1 24.5
1480
+ ...
1481
+ 3 27.8
1482
+ ;
1483
+ ods graphics on; ODS RTF;ODS LISTING CLOSE;
1484
+ PROC ANOVA DATA=ACHE;
1485
+ CLASS BRAND;
1486
+ MODEL RELIEF=BRAND;
1487
+ MEANS BRAND/TUKEY CLDIFF;
1488
+ TITLE 'COMPARE RELIEF ACROSS MEDICINES - ANOVA EXAMPLE';
1489
+ ods output CLDiffs =tc;
1490
+ proc print data=tc;
1491
+ format LowerCL 17.16 UpperCL 17.16 Difference 17.16;
1492
+ title "Output with many digits";
1493
+ RUN;
1494
+ QUIT;
1495
+ ODS RTF close;
1496
+ ODS LISTING;
1497
+ '''
1498
+ res_expect = np.asarray(res_expect_str.replace(" - ", " ").split()[5:],
1499
+ dtype=float).reshape((6, 6))
1500
+ res_tukey = stats.tukey_hsd(*data)
1501
+ conf = res_tukey.confidence_interval()
1502
+ # loop over the comparisons
1503
+ for i, j, l, s, h, sig in res_expect:
1504
+ i, j = int(i) - 1, int(j) - 1
1505
+ assert_allclose(conf.low[i, j], l, atol=atol)
1506
+ assert_allclose(res_tukey.statistic[i, j], s, atol=atol)
1507
+ assert_allclose(conf.high[i, j], h, atol=atol)
1508
+ assert_allclose((res_tukey.pvalue[i, j] <= .05), sig == 1)
1509
+
1510
+ matlab_sm_siz = """
1511
+ 1 2 -8.2491590248597 -4.6 -0.9508409751403 0.0144483269098
1512
+ 1 3 -3.9091590248597 -0.26 3.3891590248597 0.9803107240900
1513
+ 2 3 0.6908409751403 4.34 7.9891590248597 0.0203311368795
1514
+ """
1515
+
1516
+ matlab_diff_sz = """
1517
+ 1 2 -7.02207069748501 -3.645 -0.26792930251500 0.03371498443080
1518
+ 1 3 -2.68207069748500 0.695 4.07207069748500 0.85572267328807
1519
+ 2 3 0.59347644287720 4.34 8.08652355712281 0.02259047020620
1520
+ """
1521
+
1522
+ @pytest.mark.parametrize("data,res_expect_str,atol",
1523
+ ((data_same_size, matlab_sm_siz, 1e-12),
1524
+ (data_diff_size, matlab_diff_sz, 1e-7)),
1525
+ ids=["equal size sample",
1526
+ "unequal size sample"])
1527
+ def test_compare_matlab(self, data, res_expect_str, atol):
1528
+ """
1529
+ vals = [24.5, 23.5, 26.4, 27.1, 29.9, 28.4, 34.2, 29.5, 32.2, 30.1,
1530
+ 26.1, 28.3, 24.3, 26.2, 27.8]
1531
+ names = {'zero', 'zero', 'zero', 'zero', 'zero', 'one', 'one', 'one',
1532
+ 'one', 'one', 'two', 'two', 'two', 'two', 'two'}
1533
+ [p,t,stats] = anova1(vals,names,"off");
1534
+ [c,m,h,nms] = multcompare(stats, "CType","hsd");
1535
+ """
1536
+ res_expect = np.asarray(res_expect_str.split(),
1537
+ dtype=float).reshape((3, 6))
1538
+ res_tukey = stats.tukey_hsd(*data)
1539
+ conf = res_tukey.confidence_interval()
1540
+ # loop over the comparisons
1541
+ for i, j, l, s, h, p in res_expect:
1542
+ i, j = int(i) - 1, int(j) - 1
1543
+ assert_allclose(conf.low[i, j], l, atol=atol)
1544
+ assert_allclose(res_tukey.statistic[i, j], s, atol=atol)
1545
+ assert_allclose(conf.high[i, j], h, atol=atol)
1546
+ assert_allclose(res_tukey.pvalue[i, j], p, atol=atol)
1547
+
1548
+ def test_compare_r(self):
1549
+ """
1550
+ Testing against results and p-values from R:
1551
+ from: https://www.rdocumentation.org/packages/stats/versions/3.6.2/
1552
+ topics/TukeyHSD
1553
+ > require(graphics)
1554
+ > summary(fm1 <- aov(breaks ~ tension, data = warpbreaks))
1555
+ > TukeyHSD(fm1, "tension", ordered = TRUE)
1556
+ > plot(TukeyHSD(fm1, "tension"))
1557
+ Tukey multiple comparisons of means
1558
+ 95% family-wise confidence level
1559
+ factor levels have been ordered
1560
+ Fit: aov(formula = breaks ~ tension, data = warpbreaks)
1561
+ $tension
1562
+ """
1563
+ str_res = """
1564
+ diff lwr upr p adj
1565
+ 2 - 3 4.722222 -4.8376022 14.28205 0.4630831
1566
+ 1 - 3 14.722222 5.1623978 24.28205 0.0014315
1567
+ 1 - 2 10.000000 0.4401756 19.55982 0.0384598
1568
+ """
1569
+ res_expect = np.asarray(str_res.replace(" - ", " ").split()[5:],
1570
+ dtype=float).reshape((3, 6))
1571
+ data = ([26, 30, 54, 25, 70, 52, 51, 26, 67,
1572
+ 27, 14, 29, 19, 29, 31, 41, 20, 44],
1573
+ [18, 21, 29, 17, 12, 18, 35, 30, 36,
1574
+ 42, 26, 19, 16, 39, 28, 21, 39, 29],
1575
+ [36, 21, 24, 18, 10, 43, 28, 15, 26,
1576
+ 20, 21, 24, 17, 13, 15, 15, 16, 28])
1577
+
1578
+ res_tukey = stats.tukey_hsd(*data)
1579
+ conf = res_tukey.confidence_interval()
1580
+ # loop over the comparisons
1581
+ for i, j, s, l, h, p in res_expect:
1582
+ i, j = int(i) - 1, int(j) - 1
1583
+ # atols are set to the number of digits present in the r result.
1584
+ assert_allclose(conf.low[i, j], l, atol=1e-7)
1585
+ assert_allclose(res_tukey.statistic[i, j], s, atol=1e-6)
1586
+ assert_allclose(conf.high[i, j], h, atol=1e-5)
1587
+ assert_allclose(res_tukey.pvalue[i, j], p, atol=1e-7)
1588
+
1589
+ def test_engineering_stat_handbook(self):
1590
+ '''
1591
+ Example sourced from:
1592
+ https://www.itl.nist.gov/div898/handbook/prc/section4/prc471.htm
1593
+ '''
1594
+ group1 = [6.9, 5.4, 5.8, 4.6, 4.0]
1595
+ group2 = [8.3, 6.8, 7.8, 9.2, 6.5]
1596
+ group3 = [8.0, 10.5, 8.1, 6.9, 9.3]
1597
+ group4 = [5.8, 3.8, 6.1, 5.6, 6.2]
1598
+ res = stats.tukey_hsd(group1, group2, group3, group4)
1599
+ conf = res.confidence_interval()
1600
+ lower = np.asarray([
1601
+ [0, 0, 0, -2.25],
1602
+ [.29, 0, -2.93, .13],
1603
+ [1.13, 0, 0, .97],
1604
+ [0, 0, 0, 0]])
1605
+ upper = np.asarray([
1606
+ [0, 0, 0, 1.93],
1607
+ [4.47, 0, 1.25, 4.31],
1608
+ [5.31, 0, 0, 5.15],
1609
+ [0, 0, 0, 0]])
1610
+
1611
+ for (i, j) in [(1, 0), (2, 0), (0, 3), (1, 2), (2, 3)]:
1612
+ assert_allclose(conf.low[i, j], lower[i, j], atol=1e-2)
1613
+ assert_allclose(conf.high[i, j], upper[i, j], atol=1e-2)
1614
+
1615
+ def test_rand_symm(self):
1616
+ # test some expected identities of the results
1617
+ np.random.seed(1234)
1618
+ data = np.random.rand(3, 100)
1619
+ res = stats.tukey_hsd(*data)
1620
+ conf = res.confidence_interval()
1621
+ # the confidence intervals should be negated symmetric of each other
1622
+ assert_equal(conf.low, -conf.high.T)
1623
+ # the `high` and `low` center diagonals should be the same since the
1624
+ # mean difference in a self comparison is 0.
1625
+ assert_equal(np.diagonal(conf.high), conf.high[0, 0])
1626
+ assert_equal(np.diagonal(conf.low), conf.low[0, 0])
1627
+ # statistic array should be antisymmetric with zeros on the diagonal
1628
+ assert_equal(res.statistic, -res.statistic.T)
1629
+ assert_equal(np.diagonal(res.statistic), 0)
1630
+ # p-values should be symmetric and 1 when compared to itself
1631
+ assert_equal(res.pvalue, res.pvalue.T)
1632
+ assert_equal(np.diagonal(res.pvalue), 1)
1633
+
1634
+ def test_no_inf(self):
1635
+ with assert_raises(ValueError, match="...must be finite."):
1636
+ stats.tukey_hsd([1, 2, 3], [2, np.inf], [6, 7, 3])
1637
+
1638
+ def test_is_1d(self):
1639
+ with assert_raises(ValueError, match="...must be one-dimensional"):
1640
+ stats.tukey_hsd([[1, 2], [2, 3]], [2, 5], [5, 23, 6])
1641
+
1642
+ def test_no_empty(self):
1643
+ with assert_raises(ValueError, match="...must be greater than one"):
1644
+ stats.tukey_hsd([], [2, 5], [4, 5, 6])
1645
+
1646
+ def test_equal_var_input_validation(self):
1647
+ msg = "Expected a boolean value for 'equal_var'"
1648
+ with assert_raises(TypeError, match=msg):
1649
+ stats.tukey_hsd([1, 2, 3], [2, 5], [6, 7], equal_var="False")
1650
+
1651
+ @pytest.mark.parametrize("nargs", (0, 1))
1652
+ def test_not_enough_treatments(self, nargs):
1653
+ with assert_raises(ValueError, match="...more than 1 treatment."):
1654
+ stats.tukey_hsd(*([[23, 7, 3]] * nargs))
1655
+
1656
+ @pytest.mark.parametrize("cl", [-.5, 0, 1, 2])
1657
+ def test_conf_level_invalid(self, cl):
1658
+ with assert_raises(ValueError, match="must be between 0 and 1"):
1659
+ r = stats.tukey_hsd([23, 7, 3], [3, 4], [9, 4])
1660
+ r.confidence_interval(cl)
1661
+
1662
+ def test_2_args_ttest(self):
1663
+ # that with 2 treatments the `pvalue` is equal to that of `ttest_ind`
1664
+ res_tukey = stats.tukey_hsd(*self.data_diff_size[:2])
1665
+ res_ttest = stats.ttest_ind(*self.data_diff_size[:2])
1666
+ assert_allclose(res_ttest.pvalue, res_tukey.pvalue[0, 1])
1667
+ assert_allclose(res_ttest.pvalue, res_tukey.pvalue[1, 0])
1668
+
1669
+
1670
+ class TestGamesHowell:
1671
+ # data with unequal variances
1672
+ data_same_size = ([24., 23., 31., 51.],
1673
+ [34., 18., 18., 26.],
1674
+ [17., 68., 59., 7.])
1675
+
1676
+ data_diff_size = ([30., 23., 51.],
1677
+ [-81., 71., -27., 63.],
1678
+ [42., 11., 29., 19., 50.],
1679
+ [23., 22., 20., 18., 9.])
1680
+
1681
+ spss_same_size = """
1682
+ Mean Diff Lower Bound Upper Bound Sig
1683
+ 0 - 1 8.25000000 -16.5492749527311 33.0492749527311 0.558733632413559
1684
+ 0 - 2 -5.50000000 -63.6702454316458 52.6702454316458 0.941147750599221
1685
+ 1 - 2 -13.7500000 -74.3174374251372 46.8174374251372 0.682983914946841
1686
+ """
1687
+
1688
+ spss_diff_size = """
1689
+ Mean Diff Lower Bound Upper Bound Sig
1690
+ 0 - 1 28.16666667 -141.985416377670 198.318749711003 0.8727542747886180
1691
+ 0 - 2 4.466666667 -37.2830676783904 46.2164010117237 0.9752628408671710
1692
+ 0 - 3 16.26666667 -35.0933112382470 67.6266445715803 0.4262506151302880
1693
+ 1 - 2 -23.70000000 -195.315617201249 147.915617201249 0.9148950609000590
1694
+ 1 - 3 -11.90000000 -188.105478728519 164.305478728519 0.9861432250093960
1695
+ 2 - 3 11.80000000 -16.2894857524254 39.8894857524254 0.4755344436335670
1696
+ """
1697
+
1698
+ @pytest.mark.xslow
1699
+ @pytest.mark.parametrize("data, res_expect_str",
1700
+ ((data_same_size, spss_same_size),
1701
+ (data_diff_size, spss_diff_size)),
1702
+ ids=["equal size sample",
1703
+ "unequal sample size"])
1704
+ def test_compare_spss(self, data, res_expect_str):
1705
+ """
1706
+ DATA LIST LIST /Group (F1.0) Value (F8.2).
1707
+ BEGIN DATA
1708
+ 0 24
1709
+ 0 23
1710
+ 0 31
1711
+ 0 51
1712
+ 1 34
1713
+ 1 18
1714
+ 1 18
1715
+ 1 26
1716
+ 2 17
1717
+ 2 68
1718
+ 2 59
1719
+ 2 7
1720
+ END DATA.
1721
+
1722
+ ONEWAY Value BY Group
1723
+ /MISSING ANALYSIS
1724
+ /POSTHOC=GH ALPHA(0.05).
1725
+ """
1726
+ res_expect = np.asarray(
1727
+ res_expect_str.replace(" - ", " ").split()[7:],
1728
+ dtype=float).reshape(-1, 6)
1729
+ res_games = stats.tukey_hsd(*data, equal_var=False)
1730
+ conf = res_games.confidence_interval()
1731
+ # loop over the comparisons
1732
+ for i, j, s, l, h, p in res_expect:
1733
+ i, j = int(i), int(j)
1734
+ assert_allclose(res_games.statistic[i, j], s, atol=1e-8)
1735
+ assert_allclose(res_games.pvalue[i, j], p, atol=1e-8)
1736
+ assert_allclose(conf.low[i, j], l, atol=1e-6)
1737
+ assert_allclose(conf.high[i, j], h, atol=1e-5)
1738
+
1739
+ r_same_size = """
1740
+ q value Pr(>|q|)
1741
+ 1 - 0 == 0 -1.5467805948856344 0.55873362851759
1742
+ 2 - 0 == 0 0.4726721776628535 0.94114775035993
1743
+ 2 - 1 == 0 1.246837541297872 0.68298393799782
1744
+ """
1745
+
1746
+ r_diff_size = """
1747
+ q value Pr(>|q|)
1748
+ 1 - 0 == 0 -1.0589317485313876 0.87275427357438
1749
+ 2 - 0 == 0 -0.5716222106144833 0.97526284087419
1750
+ 3 - 0 == 0 -2.6209678382077000 0.42625067714691
1751
+ 2 - 1 == 0 0.8971899898179028 0.91489506061850
1752
+ 3 - 1 == 0 0.4579447210555352 0.98614322544695
1753
+ 3 - 2 == 0 -2.198800177874794 0.47553444364614
1754
+ """
1755
+
1756
+ @pytest.mark.parametrize("data, res_expect_str",
1757
+ ((data_same_size, r_same_size),
1758
+ (data_diff_size, r_diff_size)),
1759
+ ids=["equal size sample",
1760
+ "unequal sample size"])
1761
+ def test_compare_r(self, data, res_expect_str):
1762
+ """
1763
+ games-howell is provided by PMCMRplus package
1764
+ https://search.r-project.org/CRAN/refmans/PMCMRplus/html/gamesHowellTest.html
1765
+ > library("PMCMRplus")
1766
+ > options(digits=16)
1767
+ > table = data.frame(
1768
+ values = c(24., 23., 31., 51., 34., 18., 18., 26., 17., 68., 59., 7.),
1769
+ groups = c("0", "0", "0", "0", "1", "1", "1", "1", "2", "2", "2", "2")
1770
+ )
1771
+ > table$groups = as.factor(table$groups)
1772
+ > fit <-aov(values ~ groups, table)
1773
+ > res = gamesHowellTest(fit)
1774
+ > summary(res)
1775
+ """
1776
+ res_expect = np.asarray(
1777
+ res_expect_str.replace(" - ", " ")
1778
+ .replace(" == ", " ").split()[3:],
1779
+ dtype=float).reshape(-1, 5)
1780
+ res_games = stats.tukey_hsd(*data, equal_var=False)
1781
+ # loop over the comparisons
1782
+ # note confidence intervals are not provided by PMCMRplus
1783
+ for j, i, _, _, p in res_expect:
1784
+ i, j = int(i), int(j)
1785
+ assert_allclose(res_games.pvalue[i, j], p, atol=1e-7)
1786
+
1787
+ # Data validation test has been covered by TestTukeyHSD
1788
+ # like empty, 1d, inf, and lack of tretments
1789
+ # because games_howell leverage _tukey_hsd_iv()
1790
+
1791
+ class TestPoissonMeansTest:
1792
+ @pytest.mark.parametrize("c1, n1, c2, n2, p_expect", (
1793
+ # example from [1], 6. Illustrative examples: Example 1
1794
+ [0, 100, 3, 100, 0.0884],
1795
+ [2, 100, 6, 100, 0.1749]
1796
+ ))
1797
+ def test_paper_examples(self, c1, n1, c2, n2, p_expect):
1798
+ res = stats.poisson_means_test(c1, n1, c2, n2)
1799
+ assert_allclose(res.pvalue, p_expect, atol=1e-4)
1800
+
1801
+ @pytest.mark.parametrize("c1, n1, c2, n2, p_expect, alt, d", (
1802
+ # These test cases are produced by the wrapped fortran code from the
1803
+ # original authors. Using a slightly modified version of this fortran,
1804
+ # found here, https://github.com/nolanbconaway/poisson-etest,
1805
+ # additional tests were created.
1806
+ [20, 10, 20, 10, 0.9999997568929630, 'two-sided', 0],
1807
+ [10, 10, 10, 10, 0.9999998403241203, 'two-sided', 0],
1808
+ [50, 15, 1, 1, 0.09920321053409643, 'two-sided', .05],
1809
+ [3, 100, 20, 300, 0.12202725450896404, 'two-sided', 0],
1810
+ [3, 12, 4, 20, 0.40416087318539173, 'greater', 0],
1811
+ [4, 20, 3, 100, 0.008053640402974236, 'greater', 0],
1812
+ # publishing paper does not include a `less` alternative,
1813
+ # so it was calculated with switched argument order and
1814
+ # alternative="greater"
1815
+ [4, 20, 3, 10, 0.3083216325432898, 'less', 0],
1816
+ [1, 1, 50, 15, 0.09322998607245102, 'less', 0]
1817
+ ))
1818
+ def test_fortran_authors(self, c1, n1, c2, n2, p_expect, alt, d):
1819
+ res = stats.poisson_means_test(c1, n1, c2, n2, alternative=alt, diff=d)
1820
+ assert_allclose(res.pvalue, p_expect, atol=2e-6, rtol=1e-16)
1821
+
1822
+ def test_different_results(self):
1823
+ # The implementation in Fortran is known to break down at higher
1824
+ # counts and observations, so we expect different results. By
1825
+ # inspection we can infer the p-value to be near one.
1826
+ count1, count2 = 10000, 10000
1827
+ nobs1, nobs2 = 10000, 10000
1828
+ res = stats.poisson_means_test(count1, nobs1, count2, nobs2)
1829
+ assert_allclose(res.pvalue, 1)
1830
+
1831
+ def test_less_than_zero_lambda_hat2(self):
1832
+ # demonstrates behavior that fixes a known fault from original Fortran.
1833
+ # p-value should clearly be near one.
1834
+ count1, count2 = 0, 0
1835
+ nobs1, nobs2 = 1, 1
1836
+ res = stats.poisson_means_test(count1, nobs1, count2, nobs2)
1837
+ assert_allclose(res.pvalue, 1)
1838
+
1839
+ def test_input_validation(self):
1840
+ count1, count2 = 0, 0
1841
+ nobs1, nobs2 = 1, 1
1842
+
1843
+ # test non-integral events
1844
+ message = '`k1` and `k2` must be integers.'
1845
+ with assert_raises(TypeError, match=message):
1846
+ stats.poisson_means_test(.7, nobs1, count2, nobs2)
1847
+ with assert_raises(TypeError, match=message):
1848
+ stats.poisson_means_test(count1, nobs1, .7, nobs2)
1849
+
1850
+ # test negative events
1851
+ message = '`k1` and `k2` must be greater than or equal to 0.'
1852
+ with assert_raises(ValueError, match=message):
1853
+ stats.poisson_means_test(-1, nobs1, count2, nobs2)
1854
+ with assert_raises(ValueError, match=message):
1855
+ stats.poisson_means_test(count1, nobs1, -1, nobs2)
1856
+
1857
+ # test negative sample size
1858
+ message = '`n1` and `n2` must be greater than 0.'
1859
+ with assert_raises(ValueError, match=message):
1860
+ stats.poisson_means_test(count1, -1, count2, nobs2)
1861
+ with assert_raises(ValueError, match=message):
1862
+ stats.poisson_means_test(count1, nobs1, count2, -1)
1863
+
1864
+ # test negative difference
1865
+ message = 'diff must be greater than or equal to 0.'
1866
+ with assert_raises(ValueError, match=message):
1867
+ stats.poisson_means_test(count1, nobs1, count2, nobs2, diff=-1)
1868
+
1869
+ # test invalid alternative
1870
+ message = 'Alternative must be one of ...'
1871
+ with assert_raises(ValueError, match=message):
1872
+ stats.poisson_means_test(1, 2, 1, 2, alternative='error')
1873
+
1874
+
1875
+ class TestBWSTest:
1876
+
1877
+ def test_bws_input_validation(self):
1878
+ rng = np.random.default_rng(4571775098104213308)
1879
+
1880
+ x, y = rng.random(size=(2, 7))
1881
+
1882
+ message = '`x` and `y` must be exactly one-dimensional.'
1883
+ with pytest.raises(ValueError, match=message):
1884
+ stats.bws_test([x, x], [y, y])
1885
+
1886
+ message = '`x` and `y` must not contain NaNs.'
1887
+ with pytest.raises(ValueError, match=message):
1888
+ stats.bws_test([np.nan], y)
1889
+
1890
+ message = '`x` and `y` must be of nonzero size.'
1891
+ with pytest.raises(ValueError, match=message):
1892
+ stats.bws_test(x, [])
1893
+
1894
+ message = 'alternative` must be one of...'
1895
+ with pytest.raises(ValueError, match=message):
1896
+ stats.bws_test(x, y, alternative='ekki-ekki')
1897
+
1898
+ message = 'method` must be an instance of...'
1899
+ with pytest.raises(ValueError, match=message):
1900
+ stats.bws_test(x, y, method=42)
1901
+
1902
+
1903
+ def test_against_published_reference(self):
1904
+ # Test against Example 2 in bws_test Reference [1], pg 9
1905
+ # https://link.springer.com/content/pdf/10.1007/BF02762032.pdf
1906
+ x = [1, 2, 3, 4, 6, 7, 8]
1907
+ y = [5, 9, 10, 11, 12, 13, 14]
1908
+ res = stats.bws_test(x, y, alternative='two-sided')
1909
+ assert_allclose(res.statistic, 5.132, atol=1e-3)
1910
+ assert_equal(res.pvalue, 10/3432)
1911
+
1912
+
1913
+ @pytest.mark.parametrize(('alternative', 'statistic', 'pvalue'),
1914
+ [('two-sided', 1.7510204081633, 0.1264422777777),
1915
+ ('less', -1.7510204081633, 0.05754662004662),
1916
+ ('greater', -1.7510204081633, 0.9424533799534)])
1917
+ def test_against_R(self, alternative, statistic, pvalue):
1918
+ # Test against R library BWStest function bws_test
1919
+ # library(BWStest)
1920
+ # options(digits=16)
1921
+ # x = c(...)
1922
+ # y = c(...)
1923
+ # bws_test(x, y, alternative='two.sided')
1924
+ rng = np.random.default_rng(4571775098104213308)
1925
+ x, y = rng.random(size=(2, 7))
1926
+ res = stats.bws_test(x, y, alternative=alternative)
1927
+ assert_allclose(res.statistic, statistic, rtol=1e-13)
1928
+ assert_allclose(res.pvalue, pvalue, atol=1e-2, rtol=1e-1)
1929
+
1930
+ @pytest.mark.parametrize(('alternative', 'statistic', 'pvalue'),
1931
+ [('two-sided', 1.142629265891, 0.2903950180801),
1932
+ ('less', 0.99629665877411, 0.8545660222131),
1933
+ ('greater', 0.99629665877411, 0.1454339777869)])
1934
+ def test_against_R_imbalanced(self, alternative, statistic, pvalue):
1935
+ # Test against R library BWStest function bws_test
1936
+ # library(BWStest)
1937
+ # options(digits=16)
1938
+ # x = c(...)
1939
+ # y = c(...)
1940
+ # bws_test(x, y, alternative='two.sided')
1941
+ rng = np.random.default_rng(5429015622386364034)
1942
+ x = rng.random(size=9)
1943
+ y = rng.random(size=8)
1944
+ res = stats.bws_test(x, y, alternative=alternative)
1945
+ assert_allclose(res.statistic, statistic, rtol=1e-13)
1946
+ assert_allclose(res.pvalue, pvalue, atol=1e-2, rtol=1e-1)
1947
+
1948
+ def test_method(self):
1949
+ # Test that `method` parameter has the desired effect
1950
+ rng = np.random.default_rng(1520514347193347862)
1951
+ x, y = rng.random(size=(2, 10))
1952
+
1953
+ rng = np.random.default_rng(1520514347193347862)
1954
+ method = stats.PermutationMethod(n_resamples=10, rng=rng)
1955
+ res1 = stats.bws_test(x, y, method=method)
1956
+
1957
+ assert len(res1.null_distribution) == 10
1958
+
1959
+ rng = np.random.default_rng(1520514347193347862)
1960
+ method = stats.PermutationMethod(n_resamples=10, rng=rng)
1961
+ res2 = stats.bws_test(x, y, method=method)
1962
+
1963
+ assert_allclose(res1.null_distribution, res2.null_distribution)
1964
+
1965
+ rng = np.random.default_rng(5205143471933478621)
1966
+ method = stats.PermutationMethod(n_resamples=10, rng=rng)
1967
+ res3 = stats.bws_test(x, y, method=method)
1968
+
1969
+ assert not np.allclose(res3.null_distribution, res1.null_distribution)
1970
+
1971
+ def test_directions(self):
1972
+ # Sanity check of the sign of the one-sided statistic
1973
+ rng = np.random.default_rng(1520514347193347862)
1974
+ x = rng.random(size=5)
1975
+ y = x - 1
1976
+
1977
+ res = stats.bws_test(x, y, alternative='greater')
1978
+ assert res.statistic > 0
1979
+ assert_equal(res.pvalue, 1 / len(res.null_distribution))
1980
+
1981
+ res = stats.bws_test(x, y, alternative='less')
1982
+ assert res.statistic > 0
1983
+ assert_equal(res.pvalue, 1)
1984
+
1985
+ res = stats.bws_test(y, x, alternative='less')
1986
+ assert res.statistic < 0
1987
+ assert_equal(res.pvalue, 1 / len(res.null_distribution))
1988
+
1989
+ res = stats.bws_test(y, x, alternative='greater')
1990
+ assert res.statistic < 0
1991
+ assert_equal(res.pvalue, 1)