scipy 1.16.2__cp313-cp313t-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.cp313t-win_arm64.lib +0 -0
  4. scipy/_cyutility.cp313t-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.cp313t-win_arm64.lib +0 -0
  13. scipy/_lib/_ccallback_c.cp313t-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.cp313t-win_arm64.lib +0 -0
  18. scipy/_lib/_fpumode.cp313t-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.cp313t-win_arm64.lib +0 -0
  23. scipy/_lib/_test_ccallback.cp313t-win_arm64.pyd +0 -0
  24. scipy/_lib/_test_deprecation_call.cp313t-win_arm64.lib +0 -0
  25. scipy/_lib/_test_deprecation_call.cp313t-win_arm64.pyd +0 -0
  26. scipy/_lib/_test_deprecation_def.cp313t-win_arm64.lib +0 -0
  27. scipy/_lib/_test_deprecation_def.cp313t-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.cp313t-win_arm64.lib +0 -0
  35. scipy/_lib/_uarray/_uarray.cp313t-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.cp313t-win_arm64.lib +0 -0
  101. scipy/_lib/messagestream.cp313t-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.cp313t-win_arm64.lib +0 -0
  148. scipy/cluster/_hierarchy.cp313t-win_arm64.pyd +0 -0
  149. scipy/cluster/_optimal_leaf_ordering.cp313t-win_arm64.lib +0 -0
  150. scipy/cluster/_optimal_leaf_ordering.cp313t-win_arm64.pyd +0 -0
  151. scipy/cluster/_vq.cp313t-win_arm64.lib +0 -0
  152. scipy/cluster/_vq.cp313t-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.cp313t-win_arm64.lib +0 -0
  193. scipy/fft/_pocketfft/pypocketfft.cp313t-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.cp313t-win_arm64.lib +0 -0
  215. scipy/fftpack/convolve.cp313t-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.cp313t-win_arm64.lib +0 -0
  233. scipy/integrate/_dop.cp313t-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.cp313t-win_arm64.lib +0 -0
  248. scipy/integrate/_lsoda.cp313t-win_arm64.pyd +0 -0
  249. scipy/integrate/_ode.py +1395 -0
  250. scipy/integrate/_odepack.cp313t-win_arm64.lib +0 -0
  251. scipy/integrate/_odepack.cp313t-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.cp313t-win_arm64.lib +0 -0
  255. scipy/integrate/_quadpack.cp313t-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.cp313t-win_arm64.lib +0 -0
  265. scipy/integrate/_test_multivariate.cp313t-win_arm64.pyd +0 -0
  266. scipy/integrate/_test_odeint_banded.cp313t-win_arm64.lib +0 -0
  267. scipy/integrate/_test_odeint_banded.cp313t-win_arm64.pyd +0 -0
  268. scipy/integrate/_vode.cp313t-win_arm64.lib +0 -0
  269. scipy/integrate/_vode.cp313t-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.cp313t-win_arm64.lib +0 -0
  290. scipy/interpolate/_dfitpack.cp313t-win_arm64.pyd +0 -0
  291. scipy/interpolate/_dierckx.cp313t-win_arm64.lib +0 -0
  292. scipy/interpolate/_dierckx.cp313t-win_arm64.pyd +0 -0
  293. scipy/interpolate/_fitpack.cp313t-win_arm64.lib +0 -0
  294. scipy/interpolate/_fitpack.cp313t-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.cp313t-win_arm64.lib +0 -0
  300. scipy/interpolate/_interpnd.cp313t-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.cp313t-win_arm64.lib +0 -0
  307. scipy/interpolate/_ppoly.cp313t-win_arm64.pyd +0 -0
  308. scipy/interpolate/_rbf.py +290 -0
  309. scipy/interpolate/_rbfinterp.py +550 -0
  310. scipy/interpolate/_rbfinterp_pythran.cp313t-win_arm64.lib +0 -0
  311. scipy/interpolate/_rbfinterp_pythran.cp313t-win_arm64.pyd +0 -0
  312. scipy/interpolate/_rgi.py +764 -0
  313. scipy/interpolate/_rgi_cython.cp313t-win_arm64.lib +0 -0
  314. scipy/interpolate/_rgi_cython.cp313t-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.cp313t-win_arm64.lib +0 -0
  343. scipy/io/_fast_matrix_market/_fmm_core.cp313t-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.cp313t-win_arm64.lib +0 -0
  355. scipy/io/_test_fortran.cp313t-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.cp313t-win_arm64.lib +0 -0
  386. scipy/io/matlab/_mio5_utils.cp313t-win_arm64.pyd +0 -0
  387. scipy/io/matlab/_mio_utils.cp313t-win_arm64.lib +0 -0
  388. scipy/io/matlab/_mio_utils.cp313t-win_arm64.pyd +0 -0
  389. scipy/io/matlab/_miobase.py +435 -0
  390. scipy/io/matlab/_streams.cp313t-win_arm64.lib +0 -0
  391. scipy/io/matlab/_streams.cp313t-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.cp313t-win_arm64.lib +0 -0
  623. scipy/linalg/_cythonized_array_utils.cp313t-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.cp313t-win_arm64.lib +0 -0
  630. scipy/linalg/_decomp_interpolative.cp313t-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.cp313t-win_arm64.lib +0 -0
  634. scipy/linalg/_decomp_lu_cython.cp313t-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.cp313t-win_arm64.lib +0 -0
  642. scipy/linalg/_decomp_update.cp313t-win_arm64.pyd +0 -0
  643. scipy/linalg/_expm_frechet.py +417 -0
  644. scipy/linalg/_fblas.cp313t-win_arm64.lib +0 -0
  645. scipy/linalg/_fblas.cp313t-win_arm64.pyd +0 -0
  646. scipy/linalg/_flapack.cp313t-win_arm64.lib +0 -0
  647. scipy/linalg/_flapack.cp313t-win_arm64.pyd +0 -0
  648. scipy/linalg/_lapack_subroutines.h +1521 -0
  649. scipy/linalg/_linalg_pythran.cp313t-win_arm64.lib +0 -0
  650. scipy/linalg/_linalg_pythran.cp313t-win_arm64.pyd +0 -0
  651. scipy/linalg/_matfuncs.py +1050 -0
  652. scipy/linalg/_matfuncs_expm.cp313t-win_arm64.lib +0 -0
  653. scipy/linalg/_matfuncs_expm.cp313t-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.cp313t-win_arm64.lib +0 -0
  657. scipy/linalg/_matfuncs_schur_sqrtm.cp313t-win_arm64.pyd +0 -0
  658. scipy/linalg/_matfuncs_sqrtm.py +107 -0
  659. scipy/linalg/_matfuncs_sqrtm_triu.cp313t-win_arm64.lib +0 -0
  660. scipy/linalg/_matfuncs_sqrtm_triu.cp313t-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.cp313t-win_arm64.lib +0 -0
  665. scipy/linalg/_solve_toeplitz.cp313t-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.cp313t-win_arm64.lib +0 -0
  672. scipy/linalg/cython_blas.cp313t-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.cp313t-win_arm64.lib +0 -0
  676. scipy/linalg/cython_lapack.cp313t-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.cp313t-win_arm64.lib +0 -0
  728. scipy/ndimage/_ctest.cp313t-win_arm64.pyd +0 -0
  729. scipy/ndimage/_cytest.cp313t-win_arm64.lib +0 -0
  730. scipy/ndimage/_cytest.cp313t-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.cp313t-win_arm64.lib +0 -0
  738. scipy/ndimage/_nd_image.cp313t-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.cp313t-win_arm64.lib +0 -0
  742. scipy/ndimage/_ni_label.cp313t-win_arm64.pyd +0 -0
  743. scipy/ndimage/_ni_support.py +139 -0
  744. scipy/ndimage/_rank_filter_1d.cp313t-win_arm64.lib +0 -0
  745. scipy/ndimage/_rank_filter_1d.cp313t-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.cp313t-win_arm64.lib +0 -0
  768. scipy/odr/__odrpack.cp313t-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.cp313t-win_arm64.lib +0 -0
  780. scipy/optimize/_bglu_dense.cp313t-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.cp313t-win_arm64.lib +0 -0
  790. scipy/optimize/_direct.cp313t-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.cp313t-win_arm64.lib +0 -0
  795. scipy/optimize/_group_columns.cp313t-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.cp313t-win_arm64.lib +0 -0
  799. scipy/optimize/_highspy/_core.cp313t-win_arm64.pyd +0 -0
  800. scipy/optimize/_highspy/_highs_options.cp313t-win_arm64.lib +0 -0
  801. scipy/optimize/_highspy/_highs_options.cp313t-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.cp313t-win_arm64.lib +0 -0
  805. scipy/optimize/_lbfgsb.cp313t-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.cp313t-win_arm64.lib +0 -0
  816. scipy/optimize/_lsap.cp313t-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.cp313t-win_arm64.lib +0 -0
  822. scipy/optimize/_lsq/givens_elimination.cp313t-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.cp313t-win_arm64.lib +0 -0
  830. scipy/optimize/_minpack.cp313t-win_arm64.pyd +0 -0
  831. scipy/optimize/_minpack_py.py +1178 -0
  832. scipy/optimize/_moduleTNC.cp313t-win_arm64.lib +0 -0
  833. scipy/optimize/_moduleTNC.cp313t-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.cp313t-win_arm64.lib +0 -0
  839. scipy/optimize/_pava_pybind.cp313t-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.cp313t-win_arm64.lib +0 -0
  850. scipy/optimize/_slsqplib.cp313t-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.cp313t-win_arm64.lib +0 -0
  855. scipy/optimize/_trlib/_trlib.cp313t-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.cp313t-win_arm64.lib +0 -0
  877. scipy/optimize/_zeros.cp313t-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.cp313t-win_arm64.lib +0 -0
  882. scipy/optimize/cython_optimize/_zeros.cp313t-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.cp313t-win_arm64.lib +0 -0
  953. scipy/signal/_max_len_seq_inner.cp313t-win_arm64.pyd +0 -0
  954. scipy/signal/_peak_finding.py +1310 -0
  955. scipy/signal/_peak_finding_utils.cp313t-win_arm64.lib +0 -0
  956. scipy/signal/_peak_finding_utils.cp313t-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.cp313t-win_arm64.lib +0 -0
  963. scipy/signal/_sigtools.cp313t-win_arm64.pyd +0 -0
  964. scipy/signal/_sosfilt.cp313t-win_arm64.lib +0 -0
  965. scipy/signal/_sosfilt.cp313t-win_arm64.pyd +0 -0
  966. scipy/signal/_spectral_py.py +2471 -0
  967. scipy/signal/_spline.cp313t-win_arm64.lib +0 -0
  968. scipy/signal/_spline.cp313t-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.cp313t-win_arm64.lib +0 -0
  974. scipy/signal/_upfirdn_apply.cp313t-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.cp313t-win_arm64.lib +0 -0
  1021. scipy/sparse/_csparsetools.cp313t-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.cp313t-win_arm64.lib +0 -0
  1032. scipy/sparse/_sparsetools.cp313t-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.cp313t-win_arm64.lib +0 -0
  1043. scipy/sparse/csgraph/_flow.cp313t-win_arm64.pyd +0 -0
  1044. scipy/sparse/csgraph/_laplacian.py +563 -0
  1045. scipy/sparse/csgraph/_matching.cp313t-win_arm64.lib +0 -0
  1046. scipy/sparse/csgraph/_matching.cp313t-win_arm64.pyd +0 -0
  1047. scipy/sparse/csgraph/_min_spanning_tree.cp313t-win_arm64.lib +0 -0
  1048. scipy/sparse/csgraph/_min_spanning_tree.cp313t-win_arm64.pyd +0 -0
  1049. scipy/sparse/csgraph/_reordering.cp313t-win_arm64.lib +0 -0
  1050. scipy/sparse/csgraph/_reordering.cp313t-win_arm64.pyd +0 -0
  1051. scipy/sparse/csgraph/_shortest_path.cp313t-win_arm64.lib +0 -0
  1052. scipy/sparse/csgraph/_shortest_path.cp313t-win_arm64.pyd +0 -0
  1053. scipy/sparse/csgraph/_tools.cp313t-win_arm64.lib +0 -0
  1054. scipy/sparse/csgraph/_tools.cp313t-win_arm64.pyd +0 -0
  1055. scipy/sparse/csgraph/_traversal.cp313t-win_arm64.lib +0 -0
  1056. scipy/sparse/csgraph/_traversal.cp313t-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.cp313t-win_arm64.lib +0 -0
  1079. scipy/sparse/linalg/_dsolve/_superlu.cp313t-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.cp313t-win_arm64.lib +0 -0
  1089. scipy/sparse/linalg/_eigen/arpack/_arpack.cp313t-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.cp313t-win_arm64.lib +0 -0
  1122. scipy/sparse/linalg/_propack/_cpropack.cp313t-win_arm64.pyd +0 -0
  1123. scipy/sparse/linalg/_propack/_dpropack.cp313t-win_arm64.lib +0 -0
  1124. scipy/sparse/linalg/_propack/_dpropack.cp313t-win_arm64.pyd +0 -0
  1125. scipy/sparse/linalg/_propack/_spropack.cp313t-win_arm64.lib +0 -0
  1126. scipy/sparse/linalg/_propack/_spropack.cp313t-win_arm64.pyd +0 -0
  1127. scipy/sparse/linalg/_propack/_zpropack.cp313t-win_arm64.lib +0 -0
  1128. scipy/sparse/linalg/_propack/_zpropack.cp313t-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.cp313t-win_arm64.lib +0 -0
  1170. scipy/spatial/_ckdtree.cp313t-win_arm64.pyd +0 -0
  1171. scipy/spatial/_distance_pybind.cp313t-win_arm64.lib +0 -0
  1172. scipy/spatial/_distance_pybind.cp313t-win_arm64.pyd +0 -0
  1173. scipy/spatial/_distance_wrap.cp313t-win_arm64.lib +0 -0
  1174. scipy/spatial/_distance_wrap.cp313t-win_arm64.pyd +0 -0
  1175. scipy/spatial/_geometric_slerp.py +238 -0
  1176. scipy/spatial/_hausdorff.cp313t-win_arm64.lib +0 -0
  1177. scipy/spatial/_hausdorff.cp313t-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.cp313t-win_arm64.lib +0 -0
  1182. scipy/spatial/_qhull.cp313t-win_arm64.pyd +0 -0
  1183. scipy/spatial/_qhull.pyi +213 -0
  1184. scipy/spatial/_spherical_voronoi.py +341 -0
  1185. scipy/spatial/_voronoi.cp313t-win_arm64.lib +0 -0
  1186. scipy/spatial/_voronoi.cp313t-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.cp313t-win_arm64.lib +0 -0
  1236. scipy/spatial/transform/_rigid_transform.cp313t-win_arm64.pyd +0 -0
  1237. scipy/spatial/transform/_rotation.cp313t-win_arm64.lib +0 -0
  1238. scipy/spatial/transform/_rotation.cp313t-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.cp313t-win_arm64.lib +0 -0
  1252. scipy/special/_comb.cp313t-win_arm64.pyd +0 -0
  1253. scipy/special/_ellip_harm.py +214 -0
  1254. scipy/special/_ellip_harm_2.cp313t-win_arm64.lib +0 -0
  1255. scipy/special/_ellip_harm_2.cp313t-win_arm64.pyd +0 -0
  1256. scipy/special/_gufuncs.cp313t-win_arm64.lib +0 -0
  1257. scipy/special/_gufuncs.cp313t-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.cp313t-win_arm64.lib +0 -0
  1281. scipy/special/_specfun.cp313t-win_arm64.pyd +0 -0
  1282. scipy/special/_special_ufuncs.cp313t-win_arm64.lib +0 -0
  1283. scipy/special/_special_ufuncs.cp313t-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.cp313t-win_arm64.lib +0 -0
  1288. scipy/special/_test_internal.cp313t-win_arm64.pyd +0 -0
  1289. scipy/special/_test_internal.pyi +9 -0
  1290. scipy/special/_testutils.py +321 -0
  1291. scipy/special/_ufuncs.cp313t-win_arm64.lib +0 -0
  1292. scipy/special/_ufuncs.cp313t-win_arm64.pyd +0 -0
  1293. scipy/special/_ufuncs.pyi +522 -0
  1294. scipy/special/_ufuncs.pyx +13173 -0
  1295. scipy/special/_ufuncs_cxx.cp313t-win_arm64.lib +0 -0
  1296. scipy/special/_ufuncs_cxx.cp313t-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.cp313t-win_arm64.lib +0 -0
  1304. scipy/special/cython_special.cp313t-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.cp313t-win_arm64.lib +0 -0
  1376. scipy/stats/_ansari_swilk_statistics.cp313t-win_arm64.pyd +0 -0
  1377. scipy/stats/_axis_nan_policy.py +692 -0
  1378. scipy/stats/_biasedurn.cp313t-win_arm64.lib +0 -0
  1379. scipy/stats/_biasedurn.cp313t-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.cp313t-win_arm64.lib +0 -0
  1404. scipy/stats/_levy_stable/levyst.cp313t-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.cp313t-win_arm64.lib +0 -0
  1418. scipy/stats/_qmc_cy.cp313t-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.cp313t-win_arm64.lib +0 -0
  1422. scipy/stats/_qmvnt_cy.cp313t-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.cp313t-win_arm64.lib +0 -0
  1426. scipy/stats/_rcont/rcont.cp313t-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.cp313t-win_arm64.lib +0 -0
  1433. scipy/stats/_sobol.cp313t-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.cp313t-win_arm64.lib +0 -0
  1437. scipy/stats/_stats.cp313t-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.cp313t-win_arm64.lib +0 -0
  1442. scipy/stats/_stats_pythran.cp313t-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.cp313t-win_arm64.lib +0 -0
  1447. scipy/stats/_unuran/unuran_wrapper.cp313t-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,2422 @@
1
+ # Copyright (C) 2003-2005 Peter J. Verveer
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions
5
+ # are met:
6
+ #
7
+ # 1. Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ #
10
+ # 2. Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following
12
+ # disclaimer in the documentation and/or other materials provided
13
+ # with the distribution.
14
+ #
15
+ # 3. The name of the author may not be used to endorse or promote
16
+ # products derived from this software without specific prior
17
+ # written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20
+ # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25
+ # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ from collections.abc import Iterable
32
+ import numbers
33
+ import warnings
34
+ import numpy as np
35
+ import operator
36
+ import math
37
+
38
+ from scipy._lib._util import normalize_axis_index
39
+ from scipy._lib._array_api import array_namespace, is_cupy, xp_size
40
+ from . import _ni_support
41
+ from . import _nd_image
42
+ from . import _ni_docstrings
43
+ from . import _rank_filter_1d
44
+
45
+ __all__ = ['correlate1d', 'convolve1d', 'gaussian_filter1d', 'gaussian_filter',
46
+ 'prewitt', 'sobel', 'generic_laplace', 'laplace',
47
+ 'gaussian_laplace', 'generic_gradient_magnitude',
48
+ 'gaussian_gradient_magnitude', 'correlate', 'convolve',
49
+ 'uniform_filter1d', 'uniform_filter', 'minimum_filter1d',
50
+ 'maximum_filter1d', 'minimum_filter', 'maximum_filter',
51
+ 'rank_filter', 'median_filter', 'percentile_filter',
52
+ 'generic_filter1d', 'generic_filter', 'vectorized_filter']
53
+
54
+
55
+ def _vectorized_filter_iv(input, function, size, footprint, output, mode, cval, origin,
56
+ axes, batch_memory):
57
+ xp = array_namespace(input, footprint, output)
58
+
59
+ # vectorized_filter input validation and standardization
60
+ input = xp.asarray(input)
61
+
62
+ if not callable(function):
63
+ raise ValueError("`function` must be a callable.")
64
+
65
+ if size is None and footprint is None:
66
+ raise ValueError("Either `size` or `footprint` must be provided.")
67
+
68
+ if size is not None and footprint is not None:
69
+ raise ValueError("Either `size` or `footprint` may be provided, not both.")
70
+
71
+ if axes is None:
72
+ axes = tuple(range(-input.ndim, 0))
73
+ elif np.isscalar(axes):
74
+ axes = (axes,)
75
+ n_axes = len(axes)
76
+ n_batch = input.ndim - n_axes
77
+
78
+ if n_axes > input.ndim:
79
+ message = ("The length of `axes` may not exceed the dimensionality of `input`"
80
+ "(`input.ndim`).")
81
+ raise ValueError(message)
82
+
83
+ # Either footprint or size must be provided
84
+ footprinted_function = function
85
+ if size is not None:
86
+ # If provided, size must be an integer or tuple of integers.
87
+ size = (size,)*n_axes if np.isscalar(size) else tuple(size)
88
+ valid = [xp.isdtype(xp.asarray(i).dtype, 'integral') and i > 0 for i in size]
89
+ if not all(valid):
90
+ raise ValueError("All elements of `size` must be positive integers.")
91
+ else:
92
+ # If provided, `footprint` must be array-like
93
+ footprint = xp.asarray(footprint, dtype=xp.bool)
94
+ size = footprint.shape
95
+ def footprinted_function(input, *args, axis=-1, **kwargs):
96
+ return function(input[..., footprint], *args, axis=-1, **kwargs)
97
+
98
+ # And by now, the dimensionality of the footprint must equal the number of axes
99
+ if n_axes != len(size):
100
+ message = ("`axes` must be compatible with the dimensionality "
101
+ "of the window specified by `size` or `footprint`.")
102
+ raise ValueError(message)
103
+
104
+ # If this is not *equal* to the dimensionality of `input`, then `axes`
105
+ # must be a provided tuple, and its length must equal the core dimensionality.
106
+ elif n_axes < input.ndim:
107
+ if axes is None:
108
+ message = ("`axes` must be provided if the dimensionality of the window "
109
+ "(`len(size)` or `footprint.ndim`) does not equal the number "
110
+ "of axes of `input` (`input.ndim`).")
111
+ raise ValueError(message)
112
+ else:
113
+ axes = tuple(range(-n_axes, 0)) if axes is None else axes
114
+
115
+ axes = (axes,) if np.isscalar(axes) else axes
116
+
117
+ # If `origin` is provided, then it must be "broadcastable" to a tuple with length
118
+ # equal to the core dimensionality.
119
+ if origin is None:
120
+ origin = (0,) * n_axes
121
+ else:
122
+ origin = (origin,)*n_axes if np.isscalar(origin) else tuple(origin)
123
+ integral = [xp.isdtype(xp.asarray(i).dtype, 'integral') for i in origin]
124
+ if not all(integral):
125
+ raise ValueError("All elements of `origin` must be integers.")
126
+ if not len(origin) == n_axes:
127
+ message = ("`origin` must be an integer or tuple of integers with length "
128
+ "equal to the number of axes.")
129
+ raise ValueError(message)
130
+
131
+ # mode must be one of the allowed strings, and we should convert it to the
132
+ # value required by `np.pad`/`cp.pad` here.
133
+ valid_modes = {'reflect', 'constant', 'nearest', 'mirror', 'wrap',
134
+ 'grid-mirror', 'grid-constant', 'grid-wrap', 'valid'}
135
+ if mode not in valid_modes:
136
+ raise ValueError(f"`mode` must be one of {valid_modes}.")
137
+ mode_map = {'nearest': 'edge', 'reflect': 'symmetric', 'mirror': 'reflect',
138
+ 'grid-mirror': 'reflect', 'grid-constant': 'constant',
139
+ 'grid-wrap': 'wrap'}
140
+ mode = mode_map.get(mode, mode)
141
+
142
+ if mode == 'valid' and any(origin):
143
+ raise ValueError("`mode='valid'` is incompatible with use of `origin`.")
144
+
145
+ if cval is None:
146
+ cval = 0.0
147
+ elif mode != 'constant':
148
+ raise ValueError("Use of `cval` is compatible only with `mode='constant'`.")
149
+
150
+ # `cval` must be a scalar or "broadcastable" to a tuple with the same
151
+ # dimensionality of `input`. (Full input validation done by `np.pad`/`cp.pad`.)
152
+ if not xp.isdtype(xp.asarray(cval).dtype, 'numeric'):
153
+ raise ValueError("`cval` must include only numbers.")
154
+
155
+ # `batch_memory` must be a positive number.
156
+ temp = xp.asarray(batch_memory)
157
+ if temp.ndim != 0 or (not xp.isdtype(temp.dtype, 'numeric')) or temp <= 0:
158
+ raise ValueError("`batch_memory` must be positive number.")
159
+
160
+ # For simplicity, work with `axes` at the end.
161
+ working_axes = tuple(range(-n_axes, 0))
162
+ input = xp.moveaxis(input, axes, working_axes)
163
+ output = (xp.moveaxis(output, axes, working_axes)
164
+ if output is not None else output)
165
+
166
+ # Wrap the function to limit maximum memory usage, deal with `footprint`,
167
+ # and populate `output`. The latter requires some verbosity because we
168
+ # don't know the output dtype.
169
+ def wrapped_function(view, output=output):
170
+ kwargs = {'axis': working_axes}
171
+
172
+ if working_axes == ():
173
+ return footprinted_function(xp.asarray(view), **kwargs)
174
+
175
+ # for now, assume we only have to iterate over zeroth axis
176
+ chunk_size = math.prod(view.shape[1:]) * view.dtype.itemsize
177
+ slices_per_batch = min(view.shape[0], batch_memory // chunk_size)
178
+ if slices_per_batch < 1:
179
+ raise ValueError("`batch_memory` is insufficient for minimum chunk size.")
180
+
181
+ elif slices_per_batch == view.shape[0]:
182
+ if output is None:
183
+ return footprinted_function(xp.asarray(view), **kwargs)
184
+ else:
185
+ output[...] = footprinted_function(xp.asarray(view), **kwargs)
186
+ return output
187
+
188
+ for i in range(0, view.shape[0], slices_per_batch):
189
+ i2 = min(i + slices_per_batch, view.shape[0])
190
+ if output is None:
191
+ # Look at the dtype before allocating the array. (In a follow-up, we
192
+ # can also look at the shape to support non-scalar elements.)
193
+ temp = footprinted_function(xp.asarray(view[i:i2]), **kwargs)
194
+ output = xp.empty(view.shape[:-n_axes], dtype=temp.dtype)
195
+ output[i:i2, ...] = temp
196
+ else:
197
+ output[i:i2, ...] = footprinted_function(xp.asarray(view[i:i2]),
198
+ **kwargs)
199
+ return output
200
+
201
+ return (input, wrapped_function, size, mode, cval, origin,
202
+ working_axes, axes, n_axes, n_batch, xp)
203
+
204
+
205
+ @_ni_docstrings.docfiller
206
+ def vectorized_filter(input, function, *, size=None, footprint=None, output=None,
207
+ mode='reflect', cval=None, origin=None, axes=None,
208
+ batch_memory=2**30):
209
+ """Filter an array with a vectorized Python callable as the kernel
210
+
211
+ Parameters
212
+ ----------
213
+ %(input)s
214
+ function : callable
215
+ Kernel to apply over a window centered at each element of `input`.
216
+ Callable must have signature::
217
+
218
+ function(window: ndarray, *, axis: int | tuple) -> scalar
219
+
220
+ where ``axis`` specifies the axis (or axes) of ``window`` along which
221
+ the filter function is evaluated.
222
+ size : scalar or tuple, optional
223
+ See `footprint` below. Ignored if `footprint` is given.
224
+ footprint : array, optional
225
+ Either `size` or `footprint` must be defined. `size` gives
226
+ the shape that is taken from the input array, at every element
227
+ position, to define the input to the filter function.
228
+ `footprint` is a boolean array that specifies (implicitly) a
229
+ shape, but also which of the elements within this shape will get
230
+ passed to the filter function. Thus ``size=(n, m)`` is equivalent
231
+ to ``footprint=np.ones((n, m))``.
232
+ We adjust `size` to the number of dimensions indicated by `axes`.
233
+ For instance, if `axes` is ``(0, 2, 1)`` and ``n`` is passed for ``size``,
234
+ then the effective `size` is ``(n, n, n)``.
235
+ output : array, optional
236
+ The array in which to place the output. By default, an array of the dtype
237
+ returned by `function` will be created.
238
+ mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
239
+ The `mode` parameter determines how the input array is extended
240
+ beyond its boundaries. Default is 'reflect'. Behavior for each valid
241
+ value is as follows:
242
+
243
+ 'reflect' (`d c b a | a b c d | d c b a`)
244
+ The input is extended by reflecting about the edge of the last
245
+ pixel. This mode is also sometimes referred to as half-sample
246
+ symmetric.
247
+
248
+ 'constant' (`k k k k | a b c d | k k k k`)
249
+ The input is extended by filling all values beyond the edge with
250
+ the same constant value, defined by the `cval` parameter.
251
+
252
+ 'nearest' (`a a a a | a b c d | d d d d`)
253
+ The input is extended by replicating the last pixel.
254
+
255
+ 'mirror' (`d c b | a b c d | c b a`)
256
+ The input is extended by reflecting about the center of the last
257
+ pixel. This mode is also sometimes referred to as whole-sample
258
+ symmetric.
259
+
260
+ 'wrap' (`a b c d | a b c d | a b c d`)
261
+ The input is extended by wrapping around to the opposite edge.
262
+
263
+ 'valid' (`| a b c d |`)
264
+ The input is not extended; rather, the output shape is reduced depending
265
+ on the window size according to the following calculation::
266
+
267
+ window_size = np.asarray(size if size is not None else footprint.shape)
268
+ output_shape = np.asarray(input.shape)
269
+ output_shape[np.asarray(axes)] -= (window_size - 1)
270
+
271
+ %(cval)s
272
+ %(origin_multiple)s
273
+ axes : tuple of int, optional
274
+ If None, `input` is filtered along all axes. Otherwise, `input` is filtered
275
+ along the specified axes. When `axes` is specified, the dimensionality of
276
+ `footprint` and the length of any tuples used for `size` or `origin` must
277
+ match the length of `axes`. The ith axis of `footprint` and the ith element
278
+ in these tuples corresponds to the ith element of `axes`.
279
+ batch_memory : int, default: 2**30
280
+ The maximum number of bytes occupied by data in the ``window``
281
+ array passed to ``function``.
282
+
283
+ Returns
284
+ -------
285
+ output : ndarray
286
+ Filtered array. The dtype is the output dtype of `function`. If `function` is
287
+ scalar-valued when applied to a single window, the shape of the output is that
288
+ of `input` (unless ``mode=='valid'``; see `mode` documentation). If `function`
289
+ is multi-valued when applied to a single window, the placement of the
290
+ corresponding dimensions within the output shape depends entirely on the
291
+ behavior of `function`; see Examples.
292
+
293
+ See Also
294
+ --------
295
+ scipy.ndimage.generic_filter
296
+
297
+ Notes
298
+ -----
299
+ This function works by padding `input` according to `mode`, then calling the
300
+ provided `function` on chunks of a sliding window view over the padded array.
301
+ This approach is very simple and flexible, and so the function has many features
302
+ not offered by some other filter functions (e.g. memory control, ``float16``
303
+ and complex dtype support, and any NaN-handling features provided by the
304
+ `function` argument).
305
+
306
+ However, this brute-force approach may perform considerable redundant work.
307
+ Use a specialized filter (e.g. `minimum_filter` instead of this function with
308
+ `numpy.min` as the callable; `uniform_filter` instead of this function with
309
+ `numpy.mean` as the callable) when possible, as it may use a more efficient
310
+ algorithm.
311
+
312
+ When a specialized filter is not available, this function is ideal when `function`
313
+ is a vectorized, pure-Python callable. Even better performance may be possible
314
+ by passing a `scipy.LowLevelCallable` to `generic_filter`. `generic_filter` may
315
+ also be preferred for expensive callables with large filter footprints and
316
+ callables that are not vectorized (i.e. those without ``axis`` support).
317
+
318
+ This function does not provide the ``extra_arguments`` or ``extra_keywords``
319
+ arguments provided by some `ndimage` functions. There are two reasons:
320
+
321
+ - The passthrough functionality can be achieved by the user: simply wrap the
322
+ original callable in another function that provides the required arguments;
323
+ e.g., ``function=lambda input, axis: function(input, *extra_arguments, axis=axis, **extra_keywords)``.
324
+ - There are use cases for `function` to be passed additional *sliding-window data*
325
+ to `function` besides `input`. This is not yet implemented, but we reserve
326
+ these argument names for such a feature, which would add capability rather than
327
+ providing a duplicate interface to existing capability.
328
+
329
+ Examples
330
+ --------
331
+ Suppose we wish to perform a median filter with even window size on a ``float16``
332
+ image. Furthermore, the image has NaNs that we wish to be ignored (and effectively
333
+ removed by the filter). `median_filter` does not support ``float16`` data, its
334
+ behavior when NaNs are present is not defined, and for even window sizes, it does
335
+ not return the usual sample median - the average of the two middle elements. This
336
+ would be an excellent use case for `vectorized_filter` with
337
+ ``function=np.nanmedian``, which supports the required interface: it accepts a
338
+ data array of any shape as the first positional argument, and tuple of axes as
339
+ keyword argument ``axis``.
340
+
341
+ >>> import numpy as np
342
+ >>> from scipy import datasets, ndimage
343
+ >>> from scipy.ndimage import vectorized_filter
344
+ >>> import matplotlib.pyplot as plt
345
+ >>> ascent = ndimage.zoom(datasets.ascent(), 0.5).astype(np.float16)
346
+ >>> ascent[::16, ::16] = np.nan
347
+ >>> result = vectorized_filter(ascent, function=np.nanmedian, size=4)
348
+
349
+ Plot the original and filtered images.
350
+
351
+ >>> fig = plt.figure()
352
+ >>> plt.gray() # show the filtered result in grayscale
353
+ >>> ax1 = fig.add_subplot(121) # left side
354
+ >>> ax2 = fig.add_subplot(122) # right side
355
+ >>> ax1.imshow(ascent)
356
+ >>> ax2.imshow(result)
357
+ >>> fig.tight_layout()
358
+ >>> plt.show()
359
+
360
+ Another need satisfied by `vectorized_filter` is to perform multi-output
361
+ filters. For instance, suppose we wish to filter an image according to the 25th
362
+ and 75th percentiles in addition to the median. We could perform the three
363
+ filters separately.
364
+
365
+ >>> ascent = ndimage.zoom(datasets.ascent(), 0.5)
366
+ >>> def get_quantile_fun(p):
367
+ ... return lambda x, axis: np.quantile(x, p, axis=axis)
368
+ >>> ref1 = vectorized_filter(ascent, get_quantile_fun(0.25), size=4)
369
+ >>> ref2 = vectorized_filter(ascent, get_quantile_fun(0.50), size=4)
370
+ >>> ref3 = vectorized_filter(ascent, get_quantile_fun(0.75), size=4)
371
+ >>> ref = np.stack([ref1, ref2, ref3])
372
+
373
+ However, `vectorized_filter` also supports filters that return multiple outputs
374
+ as long as `output` is unspecified and `batch_memory` is sufficiently high to
375
+ perform the calculation in a single chunk.
376
+
377
+ >>> def quartiles(x, axis):
378
+ ... return np.quantile(x, [0.25, 0.50, 0.75], axis=axis)
379
+ >>> res = vectorized_filter(ascent, quartiles, size=4, batch_memory=np.inf)
380
+ >>> np.all(np.isclose(res, ref))
381
+ np.True_
382
+
383
+ The placement of the additional dimension(s) corresponding with multiple outputs
384
+ is at the discretion of `function`. `quartiles` happens to prepend one dimension
385
+ corresponding with the three outputs simply because that is the behavior of
386
+ `np.quantile`:
387
+
388
+ >>> res.shape == (3,) + ascent.shape
389
+ True
390
+
391
+ If we wished for this dimension to be appended:
392
+
393
+ >>> def quartiles(x, axis):
394
+ ... return np.moveaxis(np.quantile(x, [0.25, 0.50, 0.75], axis=axis), 0, -1)
395
+ >>> res = vectorized_filter(ascent, quartiles, size=4, batch_memory=np.inf)
396
+ >>> res.shape == ascent.shape + (3,)
397
+ True
398
+
399
+ Suppose we wish to implment a "mode" filter - a filter that selects the most
400
+ frequently occuring value within the window. A simple (but rather slow)
401
+ approach is to use `generic_filter` with `scipy.stats.mode`.
402
+
403
+ >>> from scipy import stats
404
+ >>> rng = np.random.default_rng(3195824598724609246)
405
+ >>> input = rng.integers(255, size=(50, 50)).astype(np.uint8)
406
+ >>> def simple_mode(input):
407
+ ... return stats.mode(input, axis=None).mode
408
+ >>> ref = ndimage.generic_filter(input, simple_mode, size=5)
409
+
410
+ If speed is important, `vectorized_filter` can take advantage of the performance
411
+ benefit of a vectorized callable.
412
+
413
+ >>> def vectorized_mode(x, axis=(-1,)):
414
+ ... n_axes = 1 if np.isscalar(axis) else len(axis)
415
+ ... x = np.moveaxis(x, axis, tuple(range(-n_axes, 0)))
416
+ ... x = np.reshape(x, x.shape[:-n_axes] + (-1,))
417
+ ... y = np.sort(x, axis=-1)
418
+ ... i = np.concatenate([np.ones(y.shape[:-1] + (1,), dtype=bool),
419
+ ... y[..., :-1] != y[..., 1:]], axis=-1)
420
+ ... indices = np.arange(y.size)[i.ravel()]
421
+ ... counts = np.diff(indices, append=y.size)
422
+ ... counts = np.reshape(np.repeat(counts, counts), y.shape)
423
+ ... k = np.argmax(counts, axis=-1, keepdims=True)
424
+ ... return np.take_along_axis(y, k, axis=-1)[..., 0]
425
+ >>> res = vectorized_filter(input, vectorized_mode, size=5)
426
+ >>> np.all(res == ref)
427
+ np.True_
428
+
429
+ Depending on the machine, the `vectorized_filter` version may be as much as
430
+ 100x faster.
431
+
432
+ """ # noqa: E501
433
+
434
+ (input, function, size, mode, cval, origin, working_axes, axes, n_axes, n_batch, xp
435
+ ) = _vectorized_filter_iv(input, function, size, footprint, output, mode, cval,
436
+ origin, axes, batch_memory)
437
+
438
+ # `np.pad`/`cp.pad` raises with these sorts of cases, but the best result is
439
+ # probably to return the original array. It could be argued that we should call
440
+ # the function on the empty array with `axis=None` just to determine the output
441
+ # dtype, but I can also see rationale against that.
442
+ if xp_size(input) == 0:
443
+ return xp.asarray(input)
444
+
445
+ # This seems to be defined.
446
+ if input.ndim == 0 and size == ():
447
+ return xp.asarray(function(input) if footprint is None
448
+ else function(input[footprint]))
449
+
450
+ if is_cupy(xp):
451
+ # CuPy is the only GPU backend that has `pad` (with all modes)
452
+ # and `sliding_window_view`. An enhancement would be to use
453
+ # no-copy conversion to CuPy whenever the data is on the GPU.
454
+ cp = xp # let there be no ambiguity!
455
+ swv = cp.lib.stride_tricks.sliding_window_view
456
+ pad = cp.pad
457
+ else:
458
+ # Try to perform no-copy conversion to NumPy for padding and
459
+ # `sliding_window_view`. (If that fails, fine - for now, the only
460
+ # GPU backend we support is CuPy.)
461
+ swv = np.lib.stride_tricks.sliding_window_view
462
+ pad = np.pad
463
+ input = np.asarray(input)
464
+ cval = np.asarray(cval)[()] if mode == 'constant' else None
465
+
466
+ # Border the image according to `mode` and `offset`.
467
+ if mode != 'valid':
468
+ kwargs = {'constant_values': cval} if mode == 'constant' else {}
469
+ borders = tuple((i//2 + j, (i-1)//2 - j) for i, j in zip(size, origin))
470
+ bordered_input = pad(input, ((0, 0),)*n_batch + borders, mode=mode, **kwargs)
471
+ else:
472
+ bordered_input = input
473
+
474
+ # Evaluate function with sliding window view. Function is already wrapped to
475
+ # manage memory, deal with `footprint`, populate `output`, etc.
476
+ view = swv(bordered_input, size, working_axes)
477
+ res = function(view)
478
+
479
+ # move working_axes back to original positions
480
+ return xp.moveaxis(res, working_axes, axes)
481
+
482
+
483
+ def _invalid_origin(origin, lenw):
484
+ return (origin < -(lenw // 2)) or (origin > (lenw - 1) // 2)
485
+
486
+
487
+ def _complex_via_real_components(func, input, weights, output, cval, **kwargs):
488
+ """Complex convolution via a linear combination of real convolutions."""
489
+ complex_input = input.dtype.kind == 'c'
490
+ complex_weights = weights.dtype.kind == 'c'
491
+ if complex_input and complex_weights:
492
+ # real component of the output
493
+ func(input.real, weights.real, output=output.real,
494
+ cval=np.real(cval), **kwargs)
495
+ output.real -= func(input.imag, weights.imag, output=None,
496
+ cval=np.imag(cval), **kwargs)
497
+ # imaginary component of the output
498
+ func(input.real, weights.imag, output=output.imag,
499
+ cval=np.real(cval), **kwargs)
500
+ output.imag += func(input.imag, weights.real, output=None,
501
+ cval=np.imag(cval), **kwargs)
502
+ elif complex_input:
503
+ func(input.real, weights, output=output.real, cval=np.real(cval),
504
+ **kwargs)
505
+ func(input.imag, weights, output=output.imag, cval=np.imag(cval),
506
+ **kwargs)
507
+ else:
508
+ if np.iscomplexobj(cval):
509
+ raise ValueError("Cannot provide a complex-valued cval when the "
510
+ "input is real.")
511
+ func(input, weights.real, output=output.real, cval=cval, **kwargs)
512
+ func(input, weights.imag, output=output.imag, cval=cval, **kwargs)
513
+ return output
514
+
515
+
516
+ def _expand_origin(ndim_image, axes, origin):
517
+ num_axes = len(axes)
518
+ origins = _ni_support._normalize_sequence(origin, num_axes)
519
+ if num_axes < ndim_image:
520
+ # set origin = 0 for any axes not being filtered
521
+ origins_temp = [0,] * ndim_image
522
+ for o, ax in zip(origins, axes):
523
+ origins_temp[ax] = o
524
+ origins = origins_temp
525
+ return origins
526
+
527
+
528
+ def _expand_footprint(ndim_image, axes, footprint,
529
+ footprint_name="footprint"):
530
+ num_axes = len(axes)
531
+ if num_axes < ndim_image:
532
+ if footprint.ndim != num_axes:
533
+ raise RuntimeError(f"{footprint_name}.ndim ({footprint.ndim}) "
534
+ f"must match len(axes) ({num_axes})")
535
+
536
+ footprint = np.expand_dims(
537
+ footprint,
538
+ tuple(ax for ax in range(ndim_image) if ax not in axes)
539
+ )
540
+ return footprint
541
+
542
+
543
+ def _expand_mode(ndim_image, axes, mode):
544
+ num_axes = len(axes)
545
+ if not isinstance(mode, str) and isinstance(mode, Iterable):
546
+ # set mode = 'constant' for any axes not being filtered
547
+ modes = _ni_support._normalize_sequence(mode, num_axes)
548
+ modes_temp = ['constant'] * ndim_image
549
+ for m, ax in zip(modes, axes):
550
+ modes_temp[ax] = m
551
+ mode = modes_temp
552
+ return mode
553
+
554
+
555
+ @_ni_docstrings.docfiller
556
+ def correlate1d(input, weights, axis=-1, output=None, mode="reflect",
557
+ cval=0.0, origin=0):
558
+ """Calculate a 1-D correlation along the given axis.
559
+
560
+ The lines of the array along the given axis are correlated with the
561
+ given weights.
562
+
563
+ Parameters
564
+ ----------
565
+ %(input)s
566
+ weights : array
567
+ 1-D sequence of numbers.
568
+ %(axis)s
569
+ %(output)s
570
+ %(mode_reflect)s
571
+ %(cval)s
572
+ %(origin)s
573
+
574
+ Returns
575
+ -------
576
+ result : ndarray
577
+ Correlation result. Has the same shape as `input`.
578
+
579
+ Examples
580
+ --------
581
+ >>> from scipy.ndimage import correlate1d
582
+ >>> correlate1d([2, 8, 0, 4, 1, 9, 9, 0], weights=[1, 3])
583
+ array([ 8, 26, 8, 12, 7, 28, 36, 9])
584
+ """
585
+ input = np.asarray(input)
586
+ weights = np.asarray(weights)
587
+ complex_input = input.dtype.kind == 'c'
588
+ complex_weights = weights.dtype.kind == 'c'
589
+ if complex_input or complex_weights:
590
+ if complex_weights:
591
+ weights = weights.conj()
592
+ weights = weights.astype(np.complex128, copy=False)
593
+ kwargs = dict(axis=axis, mode=mode, origin=origin)
594
+ output = _ni_support._get_output(output, input, complex_output=True)
595
+ return _complex_via_real_components(correlate1d, input, weights,
596
+ output, cval, **kwargs)
597
+
598
+ output = _ni_support._get_output(output, input)
599
+ weights = np.asarray(weights, dtype=np.float64)
600
+ if weights.ndim != 1 or weights.shape[0] < 1:
601
+ raise RuntimeError('no filter weights given')
602
+ if not weights.flags.contiguous:
603
+ weights = weights.copy()
604
+ axis = normalize_axis_index(axis, input.ndim)
605
+ if _invalid_origin(origin, len(weights)):
606
+ raise ValueError('Invalid origin; origin must satisfy '
607
+ '-(len(weights) // 2) <= origin <= '
608
+ '(len(weights)-1) // 2')
609
+ mode = _ni_support._extend_mode_to_code(mode)
610
+ _nd_image.correlate1d(input, weights, axis, output, mode, cval,
611
+ origin)
612
+ return output
613
+
614
+
615
+ @_ni_docstrings.docfiller
616
+ def convolve1d(input, weights, axis=-1, output=None, mode="reflect",
617
+ cval=0.0, origin=0):
618
+ """Calculate a 1-D convolution along the given axis.
619
+
620
+ The lines of the array along the given axis are convolved with the
621
+ given weights.
622
+
623
+ Parameters
624
+ ----------
625
+ %(input)s
626
+ weights : ndarray
627
+ 1-D sequence of numbers.
628
+ %(axis)s
629
+ %(output)s
630
+ %(mode_reflect)s
631
+ %(cval)s
632
+ %(origin)s
633
+
634
+ Returns
635
+ -------
636
+ convolve1d : ndarray
637
+ Convolved array with same shape as input
638
+
639
+ Examples
640
+ --------
641
+ >>> from scipy.ndimage import convolve1d
642
+ >>> convolve1d([2, 8, 0, 4, 1, 9, 9, 0], weights=[1, 3])
643
+ array([14, 24, 4, 13, 12, 36, 27, 0])
644
+ """
645
+ weights = np.asarray(weights)
646
+ weights = weights[::-1]
647
+ origin = -origin
648
+ if not weights.shape[0] & 1:
649
+ origin -= 1
650
+ if weights.dtype.kind == 'c':
651
+ # pre-conjugate here to counteract the conjugation in correlate1d
652
+ weights = weights.conj()
653
+ return correlate1d(input, weights, axis, output, mode, cval, origin)
654
+
655
+
656
+ def _gaussian_kernel1d(sigma, order, radius):
657
+ """
658
+ Computes a 1-D Gaussian convolution kernel.
659
+ """
660
+ if order < 0:
661
+ raise ValueError('order must be non-negative')
662
+ exponent_range = np.arange(order + 1)
663
+ sigma2 = sigma * sigma
664
+ x = np.arange(-radius, radius+1)
665
+ phi_x = np.exp(-0.5 / sigma2 * x ** 2)
666
+ phi_x = phi_x / phi_x.sum()
667
+
668
+ if order == 0:
669
+ return phi_x
670
+ else:
671
+ # f(x) = q(x) * phi(x) = q(x) * exp(p(x))
672
+ # f'(x) = (q'(x) + q(x) * p'(x)) * phi(x)
673
+ # p'(x) = -1 / sigma ** 2
674
+ # Implement q'(x) + q(x) * p'(x) as a matrix operator and apply to the
675
+ # coefficients of q(x)
676
+ q = np.zeros(order + 1)
677
+ q[0] = 1
678
+ D = np.diag(exponent_range[1:], 1) # D @ q(x) = q'(x)
679
+ P = np.diag(np.ones(order)/-sigma2, -1) # P @ q(x) = q(x) * p'(x)
680
+ Q_deriv = D + P
681
+ for _ in range(order):
682
+ q = Q_deriv.dot(q)
683
+ q = (x[:, None] ** exponent_range).dot(q)
684
+ return q * phi_x
685
+
686
+
687
+ @_ni_docstrings.docfiller
688
+ def gaussian_filter1d(input, sigma, axis=-1, order=0, output=None,
689
+ mode="reflect", cval=0.0, truncate=4.0, *, radius=None):
690
+ """1-D Gaussian filter.
691
+
692
+ Parameters
693
+ ----------
694
+ %(input)s
695
+ sigma : scalar
696
+ standard deviation for Gaussian kernel
697
+ %(axis)s
698
+ order : int, optional
699
+ An order of 0 corresponds to convolution with a Gaussian
700
+ kernel. A positive order corresponds to convolution with
701
+ that derivative of a Gaussian.
702
+ %(output)s
703
+ %(mode_reflect)s
704
+ %(cval)s
705
+ truncate : float, optional
706
+ Truncate the filter at this many standard deviations.
707
+ Default is 4.0.
708
+ radius : None or int, optional
709
+ Radius of the Gaussian kernel. If specified, the size of
710
+ the kernel will be ``2*radius + 1``, and `truncate` is ignored.
711
+ Default is None.
712
+
713
+ Returns
714
+ -------
715
+ gaussian_filter1d : ndarray
716
+
717
+ Notes
718
+ -----
719
+ The Gaussian kernel will have size ``2*radius + 1`` along each axis. If
720
+ `radius` is None, a default ``radius = round(truncate * sigma)`` will be
721
+ used.
722
+
723
+ Examples
724
+ --------
725
+ >>> from scipy.ndimage import gaussian_filter1d
726
+ >>> import numpy as np
727
+ >>> gaussian_filter1d([1.0, 2.0, 3.0, 4.0, 5.0], 1)
728
+ array([ 1.42704095, 2.06782203, 3. , 3.93217797, 4.57295905])
729
+ >>> gaussian_filter1d([1.0, 2.0, 3.0, 4.0, 5.0], 4)
730
+ array([ 2.91948343, 2.95023502, 3. , 3.04976498, 3.08051657])
731
+ >>> import matplotlib.pyplot as plt
732
+ >>> rng = np.random.default_rng()
733
+ >>> x = rng.standard_normal(101).cumsum()
734
+ >>> y3 = gaussian_filter1d(x, 3)
735
+ >>> y6 = gaussian_filter1d(x, 6)
736
+ >>> plt.plot(x, 'k', label='original data')
737
+ >>> plt.plot(y3, '--', label='filtered, sigma=3')
738
+ >>> plt.plot(y6, ':', label='filtered, sigma=6')
739
+ >>> plt.legend()
740
+ >>> plt.grid()
741
+ >>> plt.show()
742
+
743
+ """
744
+ sd = float(sigma)
745
+ # make the radius of the filter equal to truncate standard deviations
746
+ lw = int(truncate * sd + 0.5)
747
+ if radius is not None:
748
+ lw = radius
749
+ if not isinstance(lw, numbers.Integral) or lw < 0:
750
+ raise ValueError('Radius must be a nonnegative integer.')
751
+ # Since we are calling correlate, not convolve, revert the kernel
752
+ weights = _gaussian_kernel1d(sigma, order, lw)[::-1]
753
+ return correlate1d(input, weights, axis, output, mode, cval, 0)
754
+
755
+
756
+ @_ni_docstrings.docfiller
757
+ def gaussian_filter(input, sigma, order=0, output=None,
758
+ mode="reflect", cval=0.0, truncate=4.0, *, radius=None,
759
+ axes=None):
760
+ """Multidimensional Gaussian filter.
761
+
762
+ Parameters
763
+ ----------
764
+ %(input)s
765
+ sigma : scalar or sequence of scalars
766
+ Standard deviation for Gaussian kernel. The standard
767
+ deviations of the Gaussian filter are given for each axis as a
768
+ sequence, or as a single number, in which case it is equal for
769
+ all axes.
770
+ order : int or sequence of ints, optional
771
+ The order of the filter along each axis is given as a sequence
772
+ of integers, or as a single number. An order of 0 corresponds
773
+ to convolution with a Gaussian kernel. A positive order
774
+ corresponds to convolution with that derivative of a Gaussian.
775
+ %(output)s
776
+ %(mode_multiple)s
777
+ %(cval)s
778
+ truncate : float, optional
779
+ Truncate the filter at this many standard deviations.
780
+ Default is 4.0.
781
+ radius : None or int or sequence of ints, optional
782
+ Radius of the Gaussian kernel. The radius are given for each axis
783
+ as a sequence, or as a single number, in which case it is equal
784
+ for all axes. If specified, the size of the kernel along each axis
785
+ will be ``2*radius + 1``, and `truncate` is ignored.
786
+ Default is None.
787
+ axes : tuple of int or None, optional
788
+ If None, `input` is filtered along all axes. Otherwise,
789
+ `input` is filtered along the specified axes. When `axes` is
790
+ specified, any tuples used for `sigma`, `order`, `mode` and/or `radius`
791
+ must match the length of `axes`. The ith entry in any of these tuples
792
+ corresponds to the ith entry in `axes`.
793
+
794
+ Returns
795
+ -------
796
+ gaussian_filter : ndarray
797
+ Returned array of same shape as `input`.
798
+
799
+ Notes
800
+ -----
801
+ The multidimensional filter is implemented as a sequence of
802
+ 1-D convolution filters. The intermediate arrays are
803
+ stored in the same data type as the output. Therefore, for output
804
+ types with a limited precision, the results may be imprecise
805
+ because intermediate results may be stored with insufficient
806
+ precision.
807
+
808
+ The Gaussian kernel will have size ``2*radius + 1`` along each axis. If
809
+ `radius` is None, the default ``radius = round(truncate * sigma)`` will be
810
+ used.
811
+
812
+ Examples
813
+ --------
814
+ >>> from scipy.ndimage import gaussian_filter
815
+ >>> import numpy as np
816
+ >>> a = np.arange(50, step=2).reshape((5,5))
817
+ >>> a
818
+ array([[ 0, 2, 4, 6, 8],
819
+ [10, 12, 14, 16, 18],
820
+ [20, 22, 24, 26, 28],
821
+ [30, 32, 34, 36, 38],
822
+ [40, 42, 44, 46, 48]])
823
+ >>> gaussian_filter(a, sigma=1)
824
+ array([[ 4, 6, 8, 9, 11],
825
+ [10, 12, 14, 15, 17],
826
+ [20, 22, 24, 25, 27],
827
+ [29, 31, 33, 34, 36],
828
+ [35, 37, 39, 40, 42]])
829
+
830
+ >>> from scipy import datasets
831
+ >>> import matplotlib.pyplot as plt
832
+ >>> fig = plt.figure()
833
+ >>> plt.gray() # show the filtered result in grayscale
834
+ >>> ax1 = fig.add_subplot(121) # left side
835
+ >>> ax2 = fig.add_subplot(122) # right side
836
+ >>> ascent = datasets.ascent()
837
+ >>> result = gaussian_filter(ascent, sigma=5)
838
+ >>> ax1.imshow(ascent)
839
+ >>> ax2.imshow(result)
840
+ >>> plt.show()
841
+ """
842
+ input = np.asarray(input)
843
+ output = _ni_support._get_output(output, input)
844
+
845
+ axes = _ni_support._check_axes(axes, input.ndim)
846
+ num_axes = len(axes)
847
+ orders = _ni_support._normalize_sequence(order, num_axes)
848
+ sigmas = _ni_support._normalize_sequence(sigma, num_axes)
849
+ modes = _ni_support._normalize_sequence(mode, num_axes)
850
+ radiuses = _ni_support._normalize_sequence(radius, num_axes)
851
+ axes = [(axes[ii], sigmas[ii], orders[ii], modes[ii], radiuses[ii])
852
+ for ii in range(num_axes) if sigmas[ii] > 1e-15]
853
+ if len(axes) > 0:
854
+ for axis, sigma, order, mode, radius in axes:
855
+ gaussian_filter1d(input, sigma, axis, order, output,
856
+ mode, cval, truncate, radius=radius)
857
+ input = output
858
+ else:
859
+ output[...] = input[...]
860
+ return output
861
+
862
+
863
+ @_ni_docstrings.docfiller
864
+ def prewitt(input, axis=-1, output=None, mode="reflect", cval=0.0):
865
+ """Calculate a Prewitt filter.
866
+
867
+ Parameters
868
+ ----------
869
+ %(input)s
870
+ %(axis)s
871
+ %(output)s
872
+ %(mode_multiple)s
873
+ %(cval)s
874
+
875
+ Returns
876
+ -------
877
+ prewitt : ndarray
878
+ Filtered array. Has the same shape as `input`.
879
+
880
+ See Also
881
+ --------
882
+ sobel: Sobel filter
883
+
884
+ Notes
885
+ -----
886
+ This function computes the one-dimensional Prewitt filter.
887
+ Horizontal edges are emphasised with the horizontal transform (axis=0),
888
+ vertical edges with the vertical transform (axis=1), and so on for higher
889
+ dimensions. These can be combined to give the magnitude.
890
+
891
+ Examples
892
+ --------
893
+ >>> from scipy import ndimage, datasets
894
+ >>> import matplotlib.pyplot as plt
895
+ >>> import numpy as np
896
+ >>> ascent = datasets.ascent()
897
+ >>> prewitt_h = ndimage.prewitt(ascent, axis=0)
898
+ >>> prewitt_v = ndimage.prewitt(ascent, axis=1)
899
+ >>> magnitude = np.sqrt(prewitt_h ** 2 + prewitt_v ** 2)
900
+ >>> magnitude *= 255 / np.max(magnitude) # Normalization
901
+ >>> fig, axes = plt.subplots(2, 2, figsize = (8, 8))
902
+ >>> plt.gray()
903
+ >>> axes[0, 0].imshow(ascent)
904
+ >>> axes[0, 1].imshow(prewitt_h)
905
+ >>> axes[1, 0].imshow(prewitt_v)
906
+ >>> axes[1, 1].imshow(magnitude)
907
+ >>> titles = ["original", "horizontal", "vertical", "magnitude"]
908
+ >>> for i, ax in enumerate(axes.ravel()):
909
+ ... ax.set_title(titles[i])
910
+ ... ax.axis("off")
911
+ >>> plt.show()
912
+
913
+ """
914
+ input = np.asarray(input)
915
+ axis = normalize_axis_index(axis, input.ndim)
916
+ output = _ni_support._get_output(output, input)
917
+ modes = _ni_support._normalize_sequence(mode, input.ndim)
918
+ correlate1d(input, [-1, 0, 1], axis, output, modes[axis], cval, 0)
919
+ axes = [ii for ii in range(input.ndim) if ii != axis]
920
+ for ii in axes:
921
+ correlate1d(output, [1, 1, 1], ii, output, modes[ii], cval, 0,)
922
+ return output
923
+
924
+
925
+ @_ni_docstrings.docfiller
926
+ def sobel(input, axis=-1, output=None, mode="reflect", cval=0.0):
927
+ """Calculate a Sobel filter.
928
+
929
+ Parameters
930
+ ----------
931
+ %(input)s
932
+ %(axis)s
933
+ %(output)s
934
+ %(mode_multiple)s
935
+ %(cval)s
936
+
937
+ Returns
938
+ -------
939
+ sobel : ndarray
940
+ Filtered array. Has the same shape as `input`.
941
+
942
+ Notes
943
+ -----
944
+ This function computes the axis-specific Sobel gradient.
945
+ The horizontal edges can be emphasised with the horizontal transform (axis=0),
946
+ the vertical edges with the vertical transform (axis=1) and so on for higher
947
+ dimensions. These can be combined to give the magnitude.
948
+
949
+ Examples
950
+ --------
951
+ >>> from scipy import ndimage, datasets
952
+ >>> import matplotlib.pyplot as plt
953
+ >>> import numpy as np
954
+ >>> ascent = datasets.ascent().astype('int32')
955
+ >>> sobel_h = ndimage.sobel(ascent, 0) # horizontal gradient
956
+ >>> sobel_v = ndimage.sobel(ascent, 1) # vertical gradient
957
+ >>> magnitude = np.sqrt(sobel_h**2 + sobel_v**2)
958
+ >>> magnitude *= 255.0 / np.max(magnitude) # normalization
959
+ >>> fig, axs = plt.subplots(2, 2, figsize=(8, 8))
960
+ >>> plt.gray() # show the filtered result in grayscale
961
+ >>> axs[0, 0].imshow(ascent)
962
+ >>> axs[0, 1].imshow(sobel_h)
963
+ >>> axs[1, 0].imshow(sobel_v)
964
+ >>> axs[1, 1].imshow(magnitude)
965
+ >>> titles = ["original", "horizontal", "vertical", "magnitude"]
966
+ >>> for i, ax in enumerate(axs.ravel()):
967
+ ... ax.set_title(titles[i])
968
+ ... ax.axis("off")
969
+ >>> plt.show()
970
+
971
+ """
972
+ input = np.asarray(input)
973
+ axis = normalize_axis_index(axis, input.ndim)
974
+ output = _ni_support._get_output(output, input)
975
+ modes = _ni_support._normalize_sequence(mode, input.ndim)
976
+ correlate1d(input, [-1, 0, 1], axis, output, modes[axis], cval, 0)
977
+ axes = [ii for ii in range(input.ndim) if ii != axis]
978
+ for ii in axes:
979
+ correlate1d(output, [1, 2, 1], ii, output, modes[ii], cval, 0)
980
+ return output
981
+
982
+
983
+ @_ni_docstrings.docfiller
984
+ def generic_laplace(input, derivative2, output=None, mode="reflect",
985
+ cval=0.0,
986
+ extra_arguments=(),
987
+ extra_keywords=None,
988
+ *, axes=None):
989
+ """
990
+ N-D Laplace filter using a provided second derivative function.
991
+
992
+ Parameters
993
+ ----------
994
+ %(input)s
995
+ derivative2 : callable
996
+ Callable with the following signature::
997
+
998
+ derivative2(input, axis, output, mode, cval,
999
+ *extra_arguments, **extra_keywords)
1000
+
1001
+ See `extra_arguments`, `extra_keywords` below.
1002
+ %(output)s
1003
+ %(mode_multiple)s
1004
+ %(cval)s
1005
+ %(extra_keywords)s
1006
+ %(extra_arguments)s
1007
+ axes : tuple of int or None
1008
+ The axes over which to apply the filter. If a `mode` tuple is
1009
+ provided, its length must match the number of axes.
1010
+
1011
+ Returns
1012
+ -------
1013
+ generic_laplace : ndarray
1014
+ Filtered array. Has the same shape as `input`.
1015
+
1016
+ """
1017
+ if extra_keywords is None:
1018
+ extra_keywords = {}
1019
+ input = np.asarray(input)
1020
+ output = _ni_support._get_output(output, input)
1021
+ axes = _ni_support._check_axes(axes, input.ndim)
1022
+ if len(axes) > 0:
1023
+ modes = _ni_support._normalize_sequence(mode, len(axes))
1024
+ derivative2(input, axes[0], output, modes[0], cval,
1025
+ *extra_arguments, **extra_keywords)
1026
+ for ii in range(1, len(axes)):
1027
+ tmp = derivative2(input, axes[ii], output.dtype, modes[ii], cval,
1028
+ *extra_arguments, **extra_keywords)
1029
+ output += tmp
1030
+ else:
1031
+ output[...] = input[...]
1032
+ return output
1033
+
1034
+
1035
+ @_ni_docstrings.docfiller
1036
+ def laplace(input, output=None, mode="reflect", cval=0.0, *, axes=None):
1037
+ """N-D Laplace filter based on approximate second derivatives.
1038
+
1039
+ Parameters
1040
+ ----------
1041
+ %(input)s
1042
+ %(output)s
1043
+ %(mode_multiple)s
1044
+ %(cval)s
1045
+ axes : tuple of int or None
1046
+ The axes over which to apply the filter. If a `mode` tuple is
1047
+ provided, its length must match the number of axes.
1048
+
1049
+ Returns
1050
+ -------
1051
+ laplace : ndarray
1052
+ Filtered array. Has the same shape as `input`.
1053
+
1054
+ Examples
1055
+ --------
1056
+ >>> from scipy import ndimage, datasets
1057
+ >>> import matplotlib.pyplot as plt
1058
+ >>> fig = plt.figure()
1059
+ >>> plt.gray() # show the filtered result in grayscale
1060
+ >>> ax1 = fig.add_subplot(121) # left side
1061
+ >>> ax2 = fig.add_subplot(122) # right side
1062
+ >>> ascent = datasets.ascent()
1063
+ >>> result = ndimage.laplace(ascent)
1064
+ >>> ax1.imshow(ascent)
1065
+ >>> ax2.imshow(result)
1066
+ >>> plt.show()
1067
+ """
1068
+ def derivative2(input, axis, output, mode, cval):
1069
+ return correlate1d(input, [1, -2, 1], axis, output, mode, cval, 0)
1070
+ return generic_laplace(input, derivative2, output, mode, cval, axes=axes)
1071
+
1072
+
1073
+ @_ni_docstrings.docfiller
1074
+ def gaussian_laplace(input, sigma, output=None, mode="reflect",
1075
+ cval=0.0, *, axes=None, **kwargs):
1076
+ """Multidimensional Laplace filter using Gaussian second derivatives.
1077
+
1078
+ Parameters
1079
+ ----------
1080
+ %(input)s
1081
+ sigma : scalar or sequence of scalars
1082
+ The standard deviations of the Gaussian filter are given for
1083
+ each axis as a sequence, or as a single number, in which case
1084
+ it is equal for all axes.
1085
+ %(output)s
1086
+ %(mode_multiple)s
1087
+ %(cval)s
1088
+ axes : tuple of int or None
1089
+ The axes over which to apply the filter. If `sigma` or `mode` tuples
1090
+ are provided, their length must match the number of axes.
1091
+ Extra keyword arguments will be passed to gaussian_filter().
1092
+
1093
+ Returns
1094
+ -------
1095
+ gaussian_laplace : ndarray
1096
+ Filtered array. Has the same shape as `input`.
1097
+
1098
+ Examples
1099
+ --------
1100
+ >>> from scipy import ndimage, datasets
1101
+ >>> import matplotlib.pyplot as plt
1102
+ >>> ascent = datasets.ascent()
1103
+
1104
+ >>> fig = plt.figure()
1105
+ >>> plt.gray() # show the filtered result in grayscale
1106
+ >>> ax1 = fig.add_subplot(121) # left side
1107
+ >>> ax2 = fig.add_subplot(122) # right side
1108
+
1109
+ >>> result = ndimage.gaussian_laplace(ascent, sigma=1)
1110
+ >>> ax1.imshow(result)
1111
+
1112
+ >>> result = ndimage.gaussian_laplace(ascent, sigma=3)
1113
+ >>> ax2.imshow(result)
1114
+ >>> plt.show()
1115
+ """
1116
+ input = np.asarray(input)
1117
+
1118
+ def derivative2(input, axis, output, mode, cval, sigma, **kwargs):
1119
+ order = [0] * input.ndim
1120
+ order[axis] = 2
1121
+ return gaussian_filter(input, sigma, order, output, mode, cval,
1122
+ **kwargs)
1123
+
1124
+ axes = _ni_support._check_axes(axes, input.ndim)
1125
+ num_axes = len(axes)
1126
+ sigma = _ni_support._normalize_sequence(sigma, num_axes)
1127
+ if num_axes < input.ndim:
1128
+ # set sigma = 0 for any axes not being filtered
1129
+ sigma_temp = [0,] * input.ndim
1130
+ for s, ax in zip(sigma, axes):
1131
+ sigma_temp[ax] = s
1132
+ sigma = sigma_temp
1133
+
1134
+ return generic_laplace(input, derivative2, output, mode, cval,
1135
+ extra_arguments=(sigma,),
1136
+ extra_keywords=kwargs,
1137
+ axes=axes)
1138
+
1139
+
1140
+ @_ni_docstrings.docfiller
1141
+ def generic_gradient_magnitude(input, derivative, output=None,
1142
+ mode="reflect", cval=0.0,
1143
+ extra_arguments=(), extra_keywords=None,
1144
+ *, axes=None):
1145
+ """Gradient magnitude using a provided gradient function.
1146
+
1147
+ Parameters
1148
+ ----------
1149
+ %(input)s
1150
+ derivative : callable
1151
+ Callable with the following signature::
1152
+
1153
+ derivative(input, axis, output, mode, cval,
1154
+ *extra_arguments, **extra_keywords)
1155
+
1156
+ See `extra_arguments`, `extra_keywords` below.
1157
+ `derivative` can assume that `input` and `output` are ndarrays.
1158
+ Note that the output from `derivative` is modified inplace;
1159
+ be careful to copy important inputs before returning them.
1160
+ %(output)s
1161
+ %(mode_multiple)s
1162
+ %(cval)s
1163
+ %(extra_keywords)s
1164
+ %(extra_arguments)s
1165
+ axes : tuple of int or None
1166
+ The axes over which to apply the filter. If a `mode` tuple is
1167
+ provided, its length must match the number of axes.
1168
+
1169
+ Returns
1170
+ -------
1171
+ generic_gradient_magnitude : ndarray
1172
+ Filtered array. Has the same shape as `input`.
1173
+
1174
+ """
1175
+ if extra_keywords is None:
1176
+ extra_keywords = {}
1177
+ input = np.asarray(input)
1178
+ output = _ni_support._get_output(output, input)
1179
+ axes = _ni_support._check_axes(axes, input.ndim)
1180
+ if len(axes) > 0:
1181
+ modes = _ni_support._normalize_sequence(mode, len(axes))
1182
+ derivative(input, axes[0], output, modes[0], cval,
1183
+ *extra_arguments, **extra_keywords)
1184
+ np.multiply(output, output, output)
1185
+ for ii in range(1, len(axes)):
1186
+ tmp = derivative(input, axes[ii], output.dtype, modes[ii], cval,
1187
+ *extra_arguments, **extra_keywords)
1188
+ np.multiply(tmp, tmp, tmp)
1189
+ output += tmp
1190
+ # This allows the sqrt to work with a different default casting
1191
+ np.sqrt(output, output, casting='unsafe')
1192
+ else:
1193
+ output[...] = input[...]
1194
+ return output
1195
+
1196
+
1197
+ @_ni_docstrings.docfiller
1198
+ def gaussian_gradient_magnitude(input, sigma, output=None,
1199
+ mode="reflect", cval=0.0, *, axes=None,
1200
+ **kwargs):
1201
+ """Multidimensional gradient magnitude using Gaussian derivatives.
1202
+
1203
+ Parameters
1204
+ ----------
1205
+ %(input)s
1206
+ sigma : scalar or sequence of scalars
1207
+ The standard deviations of the Gaussian filter are given for
1208
+ each axis as a sequence, or as a single number, in which case
1209
+ it is equal for all axes.
1210
+ %(output)s
1211
+ %(mode_multiple)s
1212
+ %(cval)s
1213
+ axes : tuple of int or None
1214
+ The axes over which to apply the filter. If `sigma` or `mode` tuples
1215
+ are provided, their length must match the number of axes.
1216
+ Extra keyword arguments will be passed to gaussian_filter().
1217
+
1218
+ Returns
1219
+ -------
1220
+ gaussian_gradient_magnitude : ndarray
1221
+ Filtered array. Has the same shape as `input`.
1222
+
1223
+ Examples
1224
+ --------
1225
+ >>> from scipy import ndimage, datasets
1226
+ >>> import matplotlib.pyplot as plt
1227
+ >>> fig = plt.figure()
1228
+ >>> plt.gray() # show the filtered result in grayscale
1229
+ >>> ax1 = fig.add_subplot(121) # left side
1230
+ >>> ax2 = fig.add_subplot(122) # right side
1231
+ >>> ascent = datasets.ascent()
1232
+ >>> result = ndimage.gaussian_gradient_magnitude(ascent, sigma=5)
1233
+ >>> ax1.imshow(ascent)
1234
+ >>> ax2.imshow(result)
1235
+ >>> plt.show()
1236
+ """
1237
+ input = np.asarray(input)
1238
+
1239
+ def derivative(input, axis, output, mode, cval, sigma, **kwargs):
1240
+ order = [0] * input.ndim
1241
+ order[axis] = 1
1242
+ return gaussian_filter(input, sigma, order, output, mode,
1243
+ cval, **kwargs)
1244
+
1245
+ return generic_gradient_magnitude(input, derivative, output, mode,
1246
+ cval, extra_arguments=(sigma,),
1247
+ extra_keywords=kwargs, axes=axes)
1248
+
1249
+
1250
+ def _correlate_or_convolve(input, weights, output, mode, cval, origin,
1251
+ convolution, axes):
1252
+ input = np.asarray(input)
1253
+ weights = np.asarray(weights)
1254
+ complex_input = input.dtype.kind == 'c'
1255
+ complex_weights = weights.dtype.kind == 'c'
1256
+ if complex_input or complex_weights:
1257
+ if complex_weights and not convolution:
1258
+ # As for np.correlate, conjugate weights rather than input.
1259
+ weights = weights.conj()
1260
+ kwargs = dict(
1261
+ mode=mode, origin=origin, convolution=convolution, axes=axes
1262
+ )
1263
+ output = _ni_support._get_output(output, input, complex_output=True)
1264
+
1265
+ return _complex_via_real_components(_correlate_or_convolve, input,
1266
+ weights, output, cval, **kwargs)
1267
+
1268
+ axes = _ni_support._check_axes(axes, input.ndim)
1269
+ weights = np.asarray(weights, dtype=np.float64)
1270
+
1271
+ # expand weights and origins if num_axes < input.ndim
1272
+ weights = _expand_footprint(input.ndim, axes, weights, "weights")
1273
+ origins = _expand_origin(input.ndim, axes, origin)
1274
+
1275
+ wshape = [ii for ii in weights.shape if ii > 0]
1276
+ if len(wshape) != input.ndim:
1277
+ raise RuntimeError(f"weights.ndim ({len(wshape)}) must match "
1278
+ f"len(axes) ({len(axes)})")
1279
+ if convolution:
1280
+ weights = weights[tuple([slice(None, None, -1)] * weights.ndim)]
1281
+ for ii in range(len(origins)):
1282
+ origins[ii] = -origins[ii]
1283
+ if not weights.shape[ii] & 1:
1284
+ origins[ii] -= 1
1285
+ for origin, lenw in zip(origins, wshape):
1286
+ if _invalid_origin(origin, lenw):
1287
+ raise ValueError('Invalid origin; origin must satisfy '
1288
+ '-(weights.shape[k] // 2) <= origin[k] <= '
1289
+ '(weights.shape[k]-1) // 2')
1290
+
1291
+ if not weights.flags.contiguous:
1292
+ weights = weights.copy()
1293
+ output = _ni_support._get_output(output, input)
1294
+ temp_needed = np.may_share_memory(input, output)
1295
+ if temp_needed:
1296
+ # input and output arrays cannot share memory
1297
+ temp = output
1298
+ output = _ni_support._get_output(output.dtype, input)
1299
+ if not isinstance(mode, str) and isinstance(mode, Iterable):
1300
+ raise RuntimeError("A sequence of modes is not supported")
1301
+ mode = _ni_support._extend_mode_to_code(mode)
1302
+ _nd_image.correlate(input, weights, output, mode, cval, origins)
1303
+ if temp_needed:
1304
+ temp[...] = output
1305
+ output = temp
1306
+ return output
1307
+
1308
+
1309
+ @_ni_docstrings.docfiller
1310
+ def correlate(input, weights, output=None, mode='reflect', cval=0.0,
1311
+ origin=0, *, axes=None):
1312
+ """
1313
+ Multidimensional correlation.
1314
+
1315
+ The array is correlated with the given kernel.
1316
+
1317
+ Parameters
1318
+ ----------
1319
+ %(input)s
1320
+ weights : ndarray
1321
+ array of weights, same number of dimensions as input
1322
+ %(output)s
1323
+ %(mode_reflect)s
1324
+ %(cval)s
1325
+ %(origin_multiple)s
1326
+ axes : tuple of int or None, optional
1327
+ If None, `input` is filtered along all axes. Otherwise,
1328
+ `input` is filtered along the specified axes. When `axes` is
1329
+ specified, any tuples used for `mode` or `origin` must match the length
1330
+ of `axes`. The ith entry in any of these tuples corresponds to the ith
1331
+ entry in `axes`.
1332
+
1333
+ Returns
1334
+ -------
1335
+ result : ndarray
1336
+ The result of correlation of `input` with `weights`.
1337
+
1338
+ See Also
1339
+ --------
1340
+ convolve : Convolve an image with a kernel.
1341
+
1342
+ Examples
1343
+ --------
1344
+ Correlation is the process of moving a filter mask often referred to
1345
+ as kernel over the image and computing the sum of products at each location.
1346
+
1347
+ >>> from scipy.ndimage import correlate
1348
+ >>> import numpy as np
1349
+ >>> input_img = np.arange(25).reshape(5,5)
1350
+ >>> print(input_img)
1351
+ [[ 0 1 2 3 4]
1352
+ [ 5 6 7 8 9]
1353
+ [10 11 12 13 14]
1354
+ [15 16 17 18 19]
1355
+ [20 21 22 23 24]]
1356
+
1357
+ Define a kernel (weights) for correlation. In this example, it is for sum of
1358
+ center and up, down, left and right next elements.
1359
+
1360
+ >>> weights = [[0, 1, 0],
1361
+ ... [1, 1, 1],
1362
+ ... [0, 1, 0]]
1363
+
1364
+ We can calculate a correlation result:
1365
+ For example, element ``[2,2]`` is ``7 + 11 + 12 + 13 + 17 = 60``.
1366
+
1367
+ >>> correlate(input_img, weights)
1368
+ array([[ 6, 10, 15, 20, 24],
1369
+ [ 26, 30, 35, 40, 44],
1370
+ [ 51, 55, 60, 65, 69],
1371
+ [ 76, 80, 85, 90, 94],
1372
+ [ 96, 100, 105, 110, 114]])
1373
+
1374
+ """
1375
+ return _correlate_or_convolve(input, weights, output, mode, cval,
1376
+ origin, False, axes)
1377
+
1378
+
1379
+ @_ni_docstrings.docfiller
1380
+ def convolve(input, weights, output=None, mode='reflect', cval=0.0,
1381
+ origin=0, *, axes=None):
1382
+ """
1383
+ Multidimensional convolution.
1384
+
1385
+ The array is convolved with the given kernel.
1386
+
1387
+ Parameters
1388
+ ----------
1389
+ %(input)s
1390
+ weights : array_like
1391
+ Array of weights, same number of dimensions as input
1392
+ %(output)s
1393
+ %(mode_reflect)s
1394
+ cval : scalar, optional
1395
+ Value to fill past edges of input if `mode` is 'constant'. Default
1396
+ is 0.0
1397
+ origin : int or sequence, optional
1398
+ Controls the placement of the filter on the input array's pixels.
1399
+ A value of 0 (the default) centers the filter over the pixel, with
1400
+ positive values shifting the filter to the right, and negative ones
1401
+ to the left. By passing a sequence of origins with length equal to
1402
+ the number of dimensions of the input array, different shifts can
1403
+ be specified along each axis.
1404
+ axes : tuple of int or None, optional
1405
+ If None, `input` is filtered along all axes. Otherwise,
1406
+ `input` is filtered along the specified axes. When `axes` is
1407
+ specified, any tuples used for `mode` or `origin` must match the length
1408
+ of `axes`. The ith entry in any of these tuples corresponds to the ith
1409
+ entry in `axes`.
1410
+
1411
+ Returns
1412
+ -------
1413
+ result : ndarray
1414
+ The result of convolution of `input` with `weights`.
1415
+
1416
+ See Also
1417
+ --------
1418
+ correlate : Correlate an image with a kernel.
1419
+
1420
+ Notes
1421
+ -----
1422
+ Each value in result is :math:`C_i = \\sum_j{I_{i+k-j} W_j}`, where
1423
+ W is the `weights` kernel,
1424
+ j is the N-D spatial index over :math:`W`,
1425
+ I is the `input` and k is the coordinate of the center of
1426
+ W, specified by `origin` in the input parameters.
1427
+
1428
+ Examples
1429
+ --------
1430
+ Perhaps the simplest case to understand is ``mode='constant', cval=0.0``,
1431
+ because in this case borders (i.e., where the `weights` kernel, centered
1432
+ on any one value, extends beyond an edge of `input`) are treated as zeros.
1433
+
1434
+ >>> import numpy as np
1435
+ >>> a = np.array([[1, 2, 0, 0],
1436
+ ... [5, 3, 0, 4],
1437
+ ... [0, 0, 0, 7],
1438
+ ... [9, 3, 0, 0]])
1439
+ >>> k = np.array([[1,1,1],[1,1,0],[1,0,0]])
1440
+ >>> from scipy import ndimage
1441
+ >>> ndimage.convolve(a, k, mode='constant', cval=0.0)
1442
+ array([[11, 10, 7, 4],
1443
+ [10, 3, 11, 11],
1444
+ [15, 12, 14, 7],
1445
+ [12, 3, 7, 0]])
1446
+
1447
+ Setting ``cval=1.0`` is equivalent to padding the outer edge of `input`
1448
+ with 1.0's (and then extracting only the original region of the result).
1449
+
1450
+ >>> ndimage.convolve(a, k, mode='constant', cval=1.0)
1451
+ array([[13, 11, 8, 7],
1452
+ [11, 3, 11, 14],
1453
+ [16, 12, 14, 10],
1454
+ [15, 6, 10, 5]])
1455
+
1456
+ With ``mode='reflect'`` (the default), outer values are reflected at the
1457
+ edge of `input` to fill in missing values.
1458
+
1459
+ >>> b = np.array([[2, 0, 0],
1460
+ ... [1, 0, 0],
1461
+ ... [0, 0, 0]])
1462
+ >>> k = np.array([[0,1,0], [0,1,0], [0,1,0]])
1463
+ >>> ndimage.convolve(b, k, mode='reflect')
1464
+ array([[5, 0, 0],
1465
+ [3, 0, 0],
1466
+ [1, 0, 0]])
1467
+
1468
+ This includes diagonally at the corners.
1469
+
1470
+ >>> k = np.array([[1,0,0],[0,1,0],[0,0,1]])
1471
+ >>> ndimage.convolve(b, k)
1472
+ array([[4, 2, 0],
1473
+ [3, 2, 0],
1474
+ [1, 1, 0]])
1475
+
1476
+ With ``mode='nearest'``, the single nearest value in to an edge in
1477
+ `input` is repeated as many times as needed to match the overlapping
1478
+ `weights`.
1479
+
1480
+ >>> c = np.array([[2, 0, 1],
1481
+ ... [1, 0, 0],
1482
+ ... [0, 0, 0]])
1483
+ >>> k = np.array([[0, 1, 0],
1484
+ ... [0, 1, 0],
1485
+ ... [0, 1, 0],
1486
+ ... [0, 1, 0],
1487
+ ... [0, 1, 0]])
1488
+ >>> ndimage.convolve(c, k, mode='nearest')
1489
+ array([[7, 0, 3],
1490
+ [5, 0, 2],
1491
+ [3, 0, 1]])
1492
+
1493
+ """
1494
+ return _correlate_or_convolve(input, weights, output, mode, cval,
1495
+ origin, True, axes)
1496
+
1497
+
1498
+ @_ni_docstrings.docfiller
1499
+ def uniform_filter1d(input, size, axis=-1, output=None,
1500
+ mode="reflect", cval=0.0, origin=0):
1501
+ """Calculate a 1-D uniform filter along the given axis.
1502
+
1503
+ The lines of the array along the given axis are filtered with a
1504
+ uniform filter of given size.
1505
+
1506
+ Parameters
1507
+ ----------
1508
+ %(input)s
1509
+ size : int
1510
+ length of uniform filter
1511
+ %(axis)s
1512
+ %(output)s
1513
+ %(mode_reflect)s
1514
+ %(cval)s
1515
+ %(origin)s
1516
+
1517
+ Returns
1518
+ -------
1519
+ result : ndarray
1520
+ Filtered array. Has same shape as `input`.
1521
+
1522
+ Examples
1523
+ --------
1524
+ >>> from scipy.ndimage import uniform_filter1d
1525
+ >>> uniform_filter1d([2, 8, 0, 4, 1, 9, 9, 0], size=3)
1526
+ array([4, 3, 4, 1, 4, 6, 6, 3])
1527
+ """
1528
+ input = np.asarray(input)
1529
+ axis = normalize_axis_index(axis, input.ndim)
1530
+ if size < 1:
1531
+ raise RuntimeError('incorrect filter size')
1532
+ complex_output = input.dtype.kind == 'c'
1533
+ output = _ni_support._get_output(output, input,
1534
+ complex_output=complex_output)
1535
+ if (size // 2 + origin < 0) or (size // 2 + origin >= size):
1536
+ raise ValueError('invalid origin')
1537
+ mode = _ni_support._extend_mode_to_code(mode)
1538
+ if not complex_output:
1539
+ _nd_image.uniform_filter1d(input, size, axis, output, mode, cval,
1540
+ origin)
1541
+ else:
1542
+ _nd_image.uniform_filter1d(input.real, size, axis, output.real, mode,
1543
+ np.real(cval), origin)
1544
+ _nd_image.uniform_filter1d(input.imag, size, axis, output.imag, mode,
1545
+ np.imag(cval), origin)
1546
+ return output
1547
+
1548
+
1549
+ @_ni_docstrings.docfiller
1550
+ def uniform_filter(input, size=3, output=None, mode="reflect",
1551
+ cval=0.0, origin=0, *, axes=None):
1552
+ """Multidimensional uniform filter.
1553
+
1554
+ Parameters
1555
+ ----------
1556
+ %(input)s
1557
+ size : int or sequence of ints, optional
1558
+ The sizes of the uniform filter are given for each axis as a
1559
+ sequence, or as a single number, in which case the size is
1560
+ equal for all axes.
1561
+ %(output)s
1562
+ %(mode_multiple)s
1563
+ %(cval)s
1564
+ %(origin_multiple)s
1565
+ axes : tuple of int or None, optional
1566
+ If None, `input` is filtered along all axes. Otherwise,
1567
+ `input` is filtered along the specified axes. When `axes` is
1568
+ specified, any tuples used for `size`, `origin`, and/or `mode`
1569
+ must match the length of `axes`. The ith entry in any of these tuples
1570
+ corresponds to the ith entry in `axes`.
1571
+
1572
+ Returns
1573
+ -------
1574
+ uniform_filter : ndarray
1575
+ Filtered array. Has the same shape as `input`.
1576
+
1577
+ Notes
1578
+ -----
1579
+ The multidimensional filter is implemented as a sequence of
1580
+ 1-D uniform filters. The intermediate arrays are stored
1581
+ in the same data type as the output. Therefore, for output types
1582
+ with a limited precision, the results may be imprecise because
1583
+ intermediate results may be stored with insufficient precision.
1584
+
1585
+ %(nan)s
1586
+
1587
+ Examples
1588
+ --------
1589
+ >>> from scipy import ndimage, datasets
1590
+ >>> import matplotlib.pyplot as plt
1591
+ >>> fig = plt.figure()
1592
+ >>> plt.gray() # show the filtered result in grayscale
1593
+ >>> ax1 = fig.add_subplot(121) # left side
1594
+ >>> ax2 = fig.add_subplot(122) # right side
1595
+ >>> ascent = datasets.ascent()
1596
+ >>> result = ndimage.uniform_filter(ascent, size=20)
1597
+ >>> ax1.imshow(ascent)
1598
+ >>> ax2.imshow(result)
1599
+ >>> plt.show()
1600
+ """
1601
+ input = np.asarray(input)
1602
+ output = _ni_support._get_output(output, input,
1603
+ complex_output=input.dtype.kind == 'c')
1604
+ axes = _ni_support._check_axes(axes, input.ndim)
1605
+ num_axes = len(axes)
1606
+ sizes = _ni_support._normalize_sequence(size, num_axes)
1607
+ origins = _ni_support._normalize_sequence(origin, num_axes)
1608
+ modes = _ni_support._normalize_sequence(mode, num_axes)
1609
+ axes = [(axes[ii], sizes[ii], origins[ii], modes[ii])
1610
+ for ii in range(num_axes) if sizes[ii] > 1]
1611
+ if len(axes) > 0:
1612
+ for axis, size, origin, mode in axes:
1613
+ uniform_filter1d(input, int(size), axis, output, mode,
1614
+ cval, origin)
1615
+ input = output
1616
+ else:
1617
+ output[...] = input[...]
1618
+ return output
1619
+
1620
+
1621
+ @_ni_docstrings.docfiller
1622
+ def minimum_filter1d(input, size, axis=-1, output=None,
1623
+ mode="reflect", cval=0.0, origin=0):
1624
+ """Calculate a 1-D minimum filter along the given axis.
1625
+
1626
+ The lines of the array along the given axis are filtered with a
1627
+ minimum filter of given size.
1628
+
1629
+ Parameters
1630
+ ----------
1631
+ %(input)s
1632
+ size : int
1633
+ length along which to calculate 1D minimum
1634
+ %(axis)s
1635
+ %(output)s
1636
+ %(mode_reflect)s
1637
+ %(cval)s
1638
+ %(origin)s
1639
+
1640
+ Returns
1641
+ -------
1642
+ result : ndarray.
1643
+ Filtered image. Has the same shape as `input`.
1644
+
1645
+ Notes
1646
+ -----
1647
+ This function implements the MINLIST algorithm [1]_, as described by
1648
+ Richard Harter [2]_, and has a guaranteed O(n) performance, `n` being
1649
+ the `input` length, regardless of filter size.
1650
+
1651
+ References
1652
+ ----------
1653
+ .. [1] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.42.2777
1654
+ .. [2] http://www.richardhartersworld.com/cri/2001/slidingmin.html
1655
+
1656
+
1657
+ Examples
1658
+ --------
1659
+ >>> from scipy.ndimage import minimum_filter1d
1660
+ >>> minimum_filter1d([2, 8, 0, 4, 1, 9, 9, 0], size=3)
1661
+ array([2, 0, 0, 0, 1, 1, 0, 0])
1662
+ """
1663
+ input = np.asarray(input)
1664
+ if np.iscomplexobj(input):
1665
+ raise TypeError('Complex type not supported')
1666
+ axis = normalize_axis_index(axis, input.ndim)
1667
+ if size < 1:
1668
+ raise RuntimeError('incorrect filter size')
1669
+ output = _ni_support._get_output(output, input)
1670
+ if (size // 2 + origin < 0) or (size // 2 + origin >= size):
1671
+ raise ValueError('invalid origin')
1672
+ mode = _ni_support._extend_mode_to_code(mode)
1673
+ _nd_image.min_or_max_filter1d(input, size, axis, output, mode, cval,
1674
+ origin, 1)
1675
+ return output
1676
+
1677
+
1678
+ @_ni_docstrings.docfiller
1679
+ def maximum_filter1d(input, size, axis=-1, output=None,
1680
+ mode="reflect", cval=0.0, origin=0):
1681
+ """Calculate a 1-D maximum filter along the given axis.
1682
+
1683
+ The lines of the array along the given axis are filtered with a
1684
+ maximum filter of given size.
1685
+
1686
+ Parameters
1687
+ ----------
1688
+ %(input)s
1689
+ size : int
1690
+ Length along which to calculate the 1-D maximum.
1691
+ %(axis)s
1692
+ %(output)s
1693
+ %(mode_reflect)s
1694
+ %(cval)s
1695
+ %(origin)s
1696
+
1697
+ Returns
1698
+ -------
1699
+ maximum1d : ndarray, None
1700
+ Maximum-filtered array with same shape as input.
1701
+ None if `output` is not None
1702
+
1703
+ Notes
1704
+ -----
1705
+ This function implements the MAXLIST algorithm [1]_, as described by
1706
+ Richard Harter [2]_, and has a guaranteed O(n) performance, `n` being
1707
+ the `input` length, regardless of filter size.
1708
+
1709
+ References
1710
+ ----------
1711
+ .. [1] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.42.2777
1712
+ .. [2] http://www.richardhartersworld.com/cri/2001/slidingmin.html
1713
+
1714
+ Examples
1715
+ --------
1716
+ >>> from scipy.ndimage import maximum_filter1d
1717
+ >>> maximum_filter1d([2, 8, 0, 4, 1, 9, 9, 0], size=3)
1718
+ array([8, 8, 8, 4, 9, 9, 9, 9])
1719
+ """
1720
+ input = np.asarray(input)
1721
+ if np.iscomplexobj(input):
1722
+ raise TypeError('Complex type not supported')
1723
+ axis = normalize_axis_index(axis, input.ndim)
1724
+ if size < 1:
1725
+ raise RuntimeError('incorrect filter size')
1726
+ output = _ni_support._get_output(output, input)
1727
+ if (size // 2 + origin < 0) or (size // 2 + origin >= size):
1728
+ raise ValueError('invalid origin')
1729
+ mode = _ni_support._extend_mode_to_code(mode)
1730
+ _nd_image.min_or_max_filter1d(input, size, axis, output, mode, cval,
1731
+ origin, 0)
1732
+ return output
1733
+
1734
+
1735
+ def _min_or_max_filter(input, size, footprint, structure, output, mode,
1736
+ cval, origin, minimum, axes=None):
1737
+ if (size is not None) and (footprint is not None):
1738
+ warnings.warn("ignoring size because footprint is set",
1739
+ UserWarning, stacklevel=3)
1740
+ if structure is None:
1741
+ if footprint is None:
1742
+ if size is None:
1743
+ raise RuntimeError("no footprint provided")
1744
+ separable = True
1745
+ else:
1746
+ footprint = np.asarray(footprint, dtype=bool)
1747
+ if not footprint.any():
1748
+ raise ValueError("All-zero footprint is not supported.")
1749
+ if footprint.all():
1750
+ size = footprint.shape
1751
+ footprint = None
1752
+ separable = True
1753
+ else:
1754
+ separable = False
1755
+ else:
1756
+ structure = np.asarray(structure, dtype=np.float64)
1757
+ separable = False
1758
+ if footprint is None:
1759
+ footprint = np.ones(structure.shape, bool)
1760
+ else:
1761
+ footprint = np.asarray(footprint, dtype=bool)
1762
+ input = np.asarray(input)
1763
+ if np.iscomplexobj(input):
1764
+ raise TypeError("Complex type not supported")
1765
+ output = _ni_support._get_output(output, input)
1766
+ temp_needed = np.may_share_memory(input, output)
1767
+ if temp_needed:
1768
+ # input and output arrays cannot share memory
1769
+ temp = output
1770
+ output = _ni_support._get_output(output.dtype, input)
1771
+ axes = _ni_support._check_axes(axes, input.ndim)
1772
+ num_axes = len(axes)
1773
+ if separable:
1774
+ origins = _ni_support._normalize_sequence(origin, num_axes)
1775
+ sizes = _ni_support._normalize_sequence(size, num_axes)
1776
+ modes = _ni_support._normalize_sequence(mode, num_axes)
1777
+ axes = [(axes[ii], sizes[ii], origins[ii], modes[ii])
1778
+ for ii in range(len(axes)) if sizes[ii] > 1]
1779
+ if minimum:
1780
+ filter_ = minimum_filter1d
1781
+ else:
1782
+ filter_ = maximum_filter1d
1783
+ if len(axes) > 0:
1784
+ for axis, size, origin, mode in axes:
1785
+ filter_(input, int(size), axis, output, mode, cval, origin)
1786
+ input = output
1787
+ else:
1788
+ output[...] = input[...]
1789
+ else:
1790
+ # expand origins and footprint if num_axes < input.ndim
1791
+ footprint = _expand_footprint(input.ndim, axes, footprint)
1792
+ origins = _expand_origin(input.ndim, axes, origin)
1793
+
1794
+ fshape = [ii for ii in footprint.shape if ii > 0]
1795
+ if len(fshape) != input.ndim:
1796
+ raise RuntimeError(f"footprint.ndim ({footprint.ndim}) must match "
1797
+ f"len(axes) ({len(axes)})")
1798
+ for origin, lenf in zip(origins, fshape):
1799
+ if (lenf // 2 + origin < 0) or (lenf // 2 + origin >= lenf):
1800
+ raise ValueError("invalid origin")
1801
+ if not footprint.flags.contiguous:
1802
+ footprint = footprint.copy()
1803
+ if structure is not None:
1804
+ if len(structure.shape) != num_axes:
1805
+ raise RuntimeError("structure array has incorrect shape")
1806
+ if num_axes != structure.ndim:
1807
+ structure = np.expand_dims(
1808
+ structure,
1809
+ tuple(ax for ax in range(structure.ndim) if ax not in axes)
1810
+ )
1811
+ if not structure.flags.contiguous:
1812
+ structure = structure.copy()
1813
+ if not isinstance(mode, str) and isinstance(mode, Iterable):
1814
+ raise RuntimeError(
1815
+ "A sequence of modes is not supported for non-separable "
1816
+ "footprints")
1817
+ mode = _ni_support._extend_mode_to_code(mode)
1818
+ _nd_image.min_or_max_filter(input, footprint, structure, output,
1819
+ mode, cval, origins, minimum)
1820
+ if temp_needed:
1821
+ temp[...] = output
1822
+ output = temp
1823
+ return output
1824
+
1825
+
1826
+ @_ni_docstrings.docfiller
1827
+ def minimum_filter(input, size=None, footprint=None, output=None,
1828
+ mode="reflect", cval=0.0, origin=0, *, axes=None):
1829
+ """Calculate a multidimensional minimum filter.
1830
+
1831
+ Parameters
1832
+ ----------
1833
+ %(input)s
1834
+ %(size_foot)s
1835
+ %(output)s
1836
+ %(mode_multiple)s
1837
+ %(cval)s
1838
+ %(origin_multiple)s
1839
+ axes : tuple of int or None, optional
1840
+ If None, `input` is filtered along all axes. Otherwise,
1841
+ `input` is filtered along the specified axes. When `axes` is
1842
+ specified, any tuples used for `size`, `origin`, and/or `mode`
1843
+ must match the length of `axes`. The ith entry in any of these tuples
1844
+ corresponds to the ith entry in `axes`.
1845
+
1846
+ Returns
1847
+ -------
1848
+ minimum_filter : ndarray
1849
+ Filtered array. Has the same shape as `input`.
1850
+
1851
+ Notes
1852
+ -----
1853
+ A sequence of modes (one per axis) is only supported when the footprint is
1854
+ separable. Otherwise, a single mode string must be provided.
1855
+
1856
+ Examples
1857
+ --------
1858
+ >>> from scipy import ndimage, datasets
1859
+ >>> import matplotlib.pyplot as plt
1860
+ >>> fig = plt.figure()
1861
+ >>> plt.gray() # show the filtered result in grayscale
1862
+ >>> ax1 = fig.add_subplot(121) # left side
1863
+ >>> ax2 = fig.add_subplot(122) # right side
1864
+ >>> ascent = datasets.ascent()
1865
+ >>> result = ndimage.minimum_filter(ascent, size=20)
1866
+ >>> ax1.imshow(ascent)
1867
+ >>> ax2.imshow(result)
1868
+ >>> plt.show()
1869
+ """
1870
+ return _min_or_max_filter(input, size, footprint, None, output, mode,
1871
+ cval, origin, 1, axes)
1872
+
1873
+
1874
+ @_ni_docstrings.docfiller
1875
+ def maximum_filter(input, size=None, footprint=None, output=None,
1876
+ mode="reflect", cval=0.0, origin=0, *, axes=None):
1877
+ """Calculate a multidimensional maximum filter.
1878
+
1879
+ Parameters
1880
+ ----------
1881
+ %(input)s
1882
+ %(size_foot)s
1883
+ %(output)s
1884
+ %(mode_multiple)s
1885
+ %(cval)s
1886
+ %(origin_multiple)s
1887
+ axes : tuple of int or None, optional
1888
+ If None, `input` is filtered along all axes. Otherwise,
1889
+ `input` is filtered along the specified axes. When `axes` is
1890
+ specified, any tuples used for `size`, `origin`, and/or `mode`
1891
+ must match the length of `axes`. The ith entry in any of these tuples
1892
+ corresponds to the ith entry in `axes`.
1893
+
1894
+ Returns
1895
+ -------
1896
+ maximum_filter : ndarray
1897
+ Filtered array. Has the same shape as `input`.
1898
+
1899
+ Notes
1900
+ -----
1901
+ A sequence of modes (one per axis) is only supported when the footprint is
1902
+ separable. Otherwise, a single mode string must be provided.
1903
+
1904
+ %(nan)s
1905
+
1906
+ Examples
1907
+ --------
1908
+ >>> from scipy import ndimage, datasets
1909
+ >>> import matplotlib.pyplot as plt
1910
+ >>> fig = plt.figure()
1911
+ >>> plt.gray() # show the filtered result in grayscale
1912
+ >>> ax1 = fig.add_subplot(121) # left side
1913
+ >>> ax2 = fig.add_subplot(122) # right side
1914
+ >>> ascent = datasets.ascent()
1915
+ >>> result = ndimage.maximum_filter(ascent, size=20)
1916
+ >>> ax1.imshow(ascent)
1917
+ >>> ax2.imshow(result)
1918
+ >>> plt.show()
1919
+ """
1920
+ return _min_or_max_filter(input, size, footprint, None, output, mode,
1921
+ cval, origin, 0, axes)
1922
+
1923
+
1924
+ @_ni_docstrings.docfiller
1925
+ def _rank_filter(input, rank, size=None, footprint=None, output=None,
1926
+ mode="reflect", cval=0.0, origin=0, operation='rank',
1927
+ axes=None):
1928
+ if (size is not None) and (footprint is not None):
1929
+ warnings.warn("ignoring size because footprint is set",
1930
+ UserWarning, stacklevel=3)
1931
+ input = np.asarray(input)
1932
+ if np.iscomplexobj(input):
1933
+ raise TypeError('Complex type not supported')
1934
+ axes = _ni_support._check_axes(axes, input.ndim)
1935
+ num_axes = len(axes)
1936
+ if footprint is None:
1937
+ if size is None:
1938
+ raise RuntimeError("no footprint or filter size provided")
1939
+ sizes = _ni_support._normalize_sequence(size, num_axes)
1940
+ footprint = np.ones(sizes, dtype=bool)
1941
+ else:
1942
+ footprint = np.asarray(footprint, dtype=bool)
1943
+ # expand origins, footprint and modes if num_axes < input.ndim
1944
+ footprint = _expand_footprint(input.ndim, axes, footprint)
1945
+ origins = _expand_origin(input.ndim, axes, origin)
1946
+ mode = _expand_mode(input.ndim, axes, mode)
1947
+
1948
+ fshape = [ii for ii in footprint.shape if ii > 0]
1949
+ if len(fshape) != input.ndim:
1950
+ raise RuntimeError(f"footprint.ndim ({footprint.ndim}) must match "
1951
+ f"len(axes) ({len(axes)})")
1952
+ for origin, lenf in zip(origins, fshape):
1953
+ if (lenf // 2 + origin < 0) or (lenf // 2 + origin >= lenf):
1954
+ raise ValueError('invalid origin')
1955
+ if not footprint.flags.contiguous:
1956
+ footprint = footprint.copy()
1957
+ filter_size = np.where(footprint, 1, 0).sum()
1958
+ if operation == 'median':
1959
+ rank = filter_size // 2
1960
+ elif operation == 'percentile':
1961
+ percentile = rank
1962
+ if percentile < 0.0:
1963
+ percentile += 100.0
1964
+ if percentile < 0 or percentile > 100:
1965
+ raise RuntimeError('invalid percentile')
1966
+ if percentile == 100.0:
1967
+ rank = filter_size - 1
1968
+ else:
1969
+ rank = int(float(filter_size) * percentile / 100.0)
1970
+ if rank < 0:
1971
+ rank += filter_size
1972
+ if rank < 0 or rank >= filter_size:
1973
+ raise RuntimeError('rank not within filter footprint size')
1974
+ if rank == 0:
1975
+ return minimum_filter(input, None, footprint, output, mode, cval,
1976
+ origins, axes=None)
1977
+ elif rank == filter_size - 1:
1978
+ return maximum_filter(input, None, footprint, output, mode, cval,
1979
+ origins, axes=None)
1980
+ else:
1981
+ output = _ni_support._get_output(output, input)
1982
+ temp_needed = np.may_share_memory(input, output)
1983
+ if temp_needed:
1984
+ # input and output arrays cannot share memory
1985
+ temp = output
1986
+ output = _ni_support._get_output(output.dtype, input)
1987
+ if not isinstance(mode, str) and isinstance(mode, Iterable):
1988
+ raise RuntimeError(
1989
+ "A sequence of modes is not supported by non-separable rank "
1990
+ "filters")
1991
+ mode = _ni_support._extend_mode_to_code(mode, is_filter=True)
1992
+ # Some corner cases are currently not allowed to use the
1993
+ # "new"/fast 1D rank filter code, including when the
1994
+ # footprint is large compared to the array size.
1995
+ # See discussion in gh-23293; longer-term it may be possible
1996
+ # to allow the fast path for these corner cases as well,
1997
+ # if algorithmic fixes are found.
1998
+ lim2 = input.size - ((footprint.size - 1) // 2 - origin)
1999
+ if input.ndim == 1 and ((lim2 >= 0) or (input.size == 1)):
2000
+ if input.dtype in (np.int64, np.float64, np.float32):
2001
+ x = input
2002
+ x_out = output
2003
+ elif input.dtype == np.float16:
2004
+ x = input.astype('float32')
2005
+ x_out = np.empty(x.shape, dtype='float32')
2006
+ elif np.result_type(input, np.int64) == np.int64:
2007
+ x = input.astype('int64')
2008
+ x_out = np.empty(x.shape, dtype='int64')
2009
+ elif input.dtype.kind in 'biu':
2010
+ # cast any other boolean, integer or unsigned type to int64
2011
+ x = input.astype('int64')
2012
+ x_out = np.empty(x.shape, dtype='int64')
2013
+ else:
2014
+ raise RuntimeError('Unsupported array type')
2015
+ cval = x.dtype.type(cval)
2016
+ _rank_filter_1d.rank_filter(x, rank, footprint.size, x_out, mode, cval,
2017
+ origin)
2018
+ if input.dtype not in (np.int64, np.float64, np.float32):
2019
+ np.copyto(output, x_out, casting='unsafe')
2020
+ else:
2021
+ _nd_image.rank_filter(input, rank, footprint, output, mode, cval, origins)
2022
+ if temp_needed:
2023
+ temp[...] = output
2024
+ output = temp
2025
+ return output
2026
+
2027
+
2028
+ @_ni_docstrings.docfiller
2029
+ def rank_filter(input, rank, size=None, footprint=None, output=None,
2030
+ mode="reflect", cval=0.0, origin=0, *, axes=None):
2031
+ """Calculate a multidimensional rank filter.
2032
+
2033
+ Parameters
2034
+ ----------
2035
+ %(input)s
2036
+ rank : int
2037
+ The rank parameter may be less than zero, i.e., rank = -1
2038
+ indicates the largest element.
2039
+ %(size_foot)s
2040
+ %(output)s
2041
+ %(mode_reflect)s
2042
+ %(cval)s
2043
+ %(origin_multiple)s
2044
+ axes : tuple of int or None, optional
2045
+ If None, `input` is filtered along all axes. Otherwise,
2046
+ `input` is filtered along the specified axes. When `axes` is
2047
+ specified, any tuples used for `size`, `origin`, and/or `mode`
2048
+ must match the length of `axes`. The ith entry in any of these tuples
2049
+ corresponds to the ith entry in `axes`.
2050
+
2051
+ Returns
2052
+ -------
2053
+ rank_filter : ndarray
2054
+ Filtered array. Has the same shape as `input`.
2055
+
2056
+ Examples
2057
+ --------
2058
+ >>> from scipy import ndimage, datasets
2059
+ >>> import matplotlib.pyplot as plt
2060
+ >>> fig = plt.figure()
2061
+ >>> plt.gray() # show the filtered result in grayscale
2062
+ >>> ax1 = fig.add_subplot(121) # left side
2063
+ >>> ax2 = fig.add_subplot(122) # right side
2064
+ >>> ascent = datasets.ascent()
2065
+ >>> result = ndimage.rank_filter(ascent, rank=42, size=20)
2066
+ >>> ax1.imshow(ascent)
2067
+ >>> ax2.imshow(result)
2068
+ >>> plt.show()
2069
+ """
2070
+ rank = operator.index(rank)
2071
+ return _rank_filter(input, rank, size, footprint, output, mode, cval,
2072
+ origin, 'rank', axes=axes)
2073
+
2074
+
2075
+ @_ni_docstrings.docfiller
2076
+ def median_filter(input, size=None, footprint=None, output=None,
2077
+ mode="reflect", cval=0.0, origin=0, *, axes=None):
2078
+ """
2079
+ Calculate a multidimensional median filter.
2080
+
2081
+ Parameters
2082
+ ----------
2083
+ %(input)s
2084
+ %(size_foot)s
2085
+ %(output)s
2086
+ %(mode_reflect)s
2087
+ %(cval)s
2088
+ %(origin_multiple)s
2089
+ axes : tuple of int or None, optional
2090
+ If None, `input` is filtered along all axes. Otherwise,
2091
+ `input` is filtered along the specified axes. When `axes` is
2092
+ specified, any tuples used for `size`, `origin`, and/or `mode`
2093
+ must match the length of `axes`. The ith entry in any of these tuples
2094
+ corresponds to the ith entry in `axes`.
2095
+
2096
+ Returns
2097
+ -------
2098
+ median_filter : ndarray
2099
+ Filtered array. Has the same shape as `input`.
2100
+
2101
+ See Also
2102
+ --------
2103
+ scipy.signal.medfilt2d
2104
+
2105
+ Notes
2106
+ -----
2107
+ For 2-dimensional images with ``uint8``, ``float32`` or ``float64`` dtypes
2108
+ the specialised function `scipy.signal.medfilt2d` may be faster. It is
2109
+ however limited to constant mode with ``cval=0``.
2110
+
2111
+ The filter always returns the argument that would appear at index ``n // 2`` in
2112
+ a sorted array, where ``n`` is the number of elements in the footprint of the
2113
+ filter. Note that this differs from the conventional definition of the median
2114
+ when ``n`` is even. Also, this function does not support the ``float16`` dtype,
2115
+ behavior in the presence of NaNs is undefined, and memory consumption scales with
2116
+ ``n**4``. For ``float16`` support, greater control over the definition of the
2117
+ filter, and to limit memory usage, consider using `vectorized_filter` with
2118
+ NumPy functions `np.median` or `np.nanmedian`.
2119
+
2120
+ Examples
2121
+ --------
2122
+ >>> from scipy import ndimage, datasets
2123
+ >>> import matplotlib.pyplot as plt
2124
+ >>> fig = plt.figure()
2125
+ >>> plt.gray() # show the filtered result in grayscale
2126
+ >>> ax1 = fig.add_subplot(121) # left side
2127
+ >>> ax2 = fig.add_subplot(122) # right side
2128
+ >>> ascent = datasets.ascent()
2129
+ >>> result = ndimage.median_filter(ascent, size=20)
2130
+ >>> ax1.imshow(ascent)
2131
+ >>> ax2.imshow(result)
2132
+ >>> plt.show()
2133
+ """
2134
+ return _rank_filter(input, 0, size, footprint, output, mode, cval,
2135
+ origin, 'median', axes=axes)
2136
+
2137
+
2138
+ @_ni_docstrings.docfiller
2139
+ def percentile_filter(input, percentile, size=None, footprint=None,
2140
+ output=None, mode="reflect", cval=0.0, origin=0, *,
2141
+ axes=None):
2142
+ """Calculate a multidimensional percentile filter.
2143
+
2144
+ Parameters
2145
+ ----------
2146
+ %(input)s
2147
+ percentile : scalar
2148
+ The percentile parameter may be less than zero, i.e.,
2149
+ percentile = -20 equals percentile = 80
2150
+ %(size_foot)s
2151
+ %(output)s
2152
+ %(mode_reflect)s
2153
+ %(cval)s
2154
+ %(origin_multiple)s
2155
+ axes : tuple of int or None, optional
2156
+ If None, `input` is filtered along all axes. Otherwise,
2157
+ `input` is filtered along the specified axes. When `axes` is
2158
+ specified, any tuples used for `size`, `origin`, and/or `mode`
2159
+ must match the length of `axes`. The ith entry in any of these tuples
2160
+ corresponds to the ith entry in `axes`.
2161
+
2162
+ Returns
2163
+ -------
2164
+ percentile_filter : ndarray
2165
+ Filtered array. Has the same shape as `input`.
2166
+
2167
+ Examples
2168
+ --------
2169
+ >>> from scipy import ndimage, datasets
2170
+ >>> import matplotlib.pyplot as plt
2171
+ >>> fig = plt.figure()
2172
+ >>> plt.gray() # show the filtered result in grayscale
2173
+ >>> ax1 = fig.add_subplot(121) # left side
2174
+ >>> ax2 = fig.add_subplot(122) # right side
2175
+ >>> ascent = datasets.ascent()
2176
+ >>> result = ndimage.percentile_filter(ascent, percentile=20, size=20)
2177
+ >>> ax1.imshow(ascent)
2178
+ >>> ax2.imshow(result)
2179
+ >>> plt.show()
2180
+ """
2181
+ return _rank_filter(input, percentile, size, footprint, output, mode,
2182
+ cval, origin, 'percentile', axes=axes)
2183
+
2184
+
2185
+ @_ni_docstrings.docfiller
2186
+ def generic_filter1d(input, function, filter_size, axis=-1,
2187
+ output=None, mode="reflect", cval=0.0, origin=0,
2188
+ extra_arguments=(), extra_keywords=None):
2189
+ """Calculate a 1-D filter along the given axis.
2190
+
2191
+ `generic_filter1d` iterates over the lines of the array, calling the
2192
+ given function at each line. The arguments of the line are the
2193
+ input line, and the output line. The input and output lines are 1-D
2194
+ double arrays. The input line is extended appropriately according
2195
+ to the filter size and origin. The output line must be modified
2196
+ in-place with the result.
2197
+
2198
+ Parameters
2199
+ ----------
2200
+ %(input)s
2201
+ function : {callable, scipy.LowLevelCallable}
2202
+ Function to apply along given axis.
2203
+ filter_size : scalar
2204
+ Length of the filter.
2205
+ %(axis)s
2206
+ %(output)s
2207
+ %(mode_reflect)s
2208
+ %(cval)s
2209
+ %(origin)s
2210
+ %(extra_arguments)s
2211
+ %(extra_keywords)s
2212
+
2213
+ Returns
2214
+ -------
2215
+ generic_filter1d : ndarray
2216
+ Filtered array. Has the same shape as `input`.
2217
+
2218
+ Notes
2219
+ -----
2220
+ This function also accepts low-level callback functions with one of
2221
+ the following signatures and wrapped in `scipy.LowLevelCallable`:
2222
+
2223
+ .. code:: c
2224
+
2225
+ int function(double *input_line, npy_intp input_length,
2226
+ double *output_line, npy_intp output_length,
2227
+ void *user_data)
2228
+ int function(double *input_line, intptr_t input_length,
2229
+ double *output_line, intptr_t output_length,
2230
+ void *user_data)
2231
+
2232
+ The calling function iterates over the lines of the input and output
2233
+ arrays, calling the callback function at each line. The current line
2234
+ is extended according to the border conditions set by the calling
2235
+ function, and the result is copied into the array that is passed
2236
+ through ``input_line``. The length of the input line (after extension)
2237
+ is passed through ``input_length``. The callback function should apply
2238
+ the filter and store the result in the array passed through
2239
+ ``output_line``. The length of the output line is passed through
2240
+ ``output_length``. ``user_data`` is the data pointer provided
2241
+ to `scipy.LowLevelCallable` as-is.
2242
+
2243
+ The callback function must return an integer error status that is zero
2244
+ if something went wrong and one otherwise. If an error occurs, you should
2245
+ normally set the python error status with an informative message
2246
+ before returning, otherwise a default error message is set by the
2247
+ calling function.
2248
+
2249
+ In addition, some other low-level function pointer specifications
2250
+ are accepted, but these are for backward compatibility only and should
2251
+ not be used in new code.
2252
+
2253
+ """
2254
+ if extra_keywords is None:
2255
+ extra_keywords = {}
2256
+ input = np.asarray(input)
2257
+ if np.iscomplexobj(input):
2258
+ raise TypeError('Complex type not supported')
2259
+ output = _ni_support._get_output(output, input)
2260
+ if filter_size < 1:
2261
+ raise RuntimeError('invalid filter size')
2262
+ axis = normalize_axis_index(axis, input.ndim)
2263
+ if (filter_size // 2 + origin < 0) or (filter_size // 2 + origin >=
2264
+ filter_size):
2265
+ raise ValueError('invalid origin')
2266
+ mode = _ni_support._extend_mode_to_code(mode)
2267
+ _nd_image.generic_filter1d(input, function, filter_size, axis, output,
2268
+ mode, cval, origin, extra_arguments,
2269
+ extra_keywords)
2270
+ return output
2271
+
2272
+
2273
+ @_ni_docstrings.docfiller
2274
+ def generic_filter(input, function, size=None, footprint=None,
2275
+ output=None, mode="reflect", cval=0.0, origin=0,
2276
+ extra_arguments=(), extra_keywords=None, *, axes=None):
2277
+ """Calculate a multidimensional filter using the given function.
2278
+
2279
+ At each element the provided function is called. The input values
2280
+ within the filter footprint at that element are passed to the function
2281
+ as a 1-D array of double values.
2282
+
2283
+ Parameters
2284
+ ----------
2285
+ %(input)s
2286
+ function : {callable, scipy.LowLevelCallable}
2287
+ Function to apply at each element.
2288
+ %(size_foot)s
2289
+ %(output)s
2290
+ %(mode_reflect)s
2291
+ %(cval)s
2292
+ %(origin_multiple)s
2293
+ %(extra_arguments)s
2294
+ %(extra_keywords)s
2295
+ axes : tuple of int or None, optional
2296
+ If None, `input` is filtered along all axes. Otherwise,
2297
+ `input` is filtered along the specified axes. When `axes` is
2298
+ specified, any tuples used for `size` or `origin` must match the length
2299
+ of `axes`. The ith entry in any of these tuples corresponds to the ith
2300
+ entry in `axes`.
2301
+
2302
+ Returns
2303
+ -------
2304
+ output : ndarray
2305
+ Filtered array. Has the same shape as `input`.
2306
+
2307
+ See Also
2308
+ --------
2309
+ vectorized_filter : similar functionality, but optimized for vectorized callables
2310
+
2311
+ Notes
2312
+ -----
2313
+ This function is ideal for use with instances of `scipy.LowLevelCallable`;
2314
+ for vectorized, pure-Python callables, consider `vectorized_filter` for improved
2315
+ performance.
2316
+
2317
+ Low-level callback functions must have one of the following signatures:
2318
+
2319
+ .. code:: c
2320
+
2321
+ int callback(double *buffer, npy_intp filter_size,
2322
+ double *return_value, void *user_data)
2323
+ int callback(double *buffer, intptr_t filter_size,
2324
+ double *return_value, void *user_data)
2325
+
2326
+ The calling function iterates over the elements of the input and
2327
+ output arrays, calling the callback function at each element. The
2328
+ elements within the footprint of the filter at the current element are
2329
+ passed through the ``buffer`` parameter, and the number of elements
2330
+ within the footprint through ``filter_size``. The calculated value is
2331
+ returned in ``return_value``. ``user_data`` is the data pointer provided
2332
+ to `scipy.LowLevelCallable` as-is.
2333
+
2334
+ The callback function must return an integer error status that is zero
2335
+ if something went wrong and one otherwise. If an error occurs, you should
2336
+ normally set the python error status with an informative message
2337
+ before returning, otherwise a default error message is set by the
2338
+ calling function.
2339
+
2340
+ In addition, some other low-level function pointer specifications
2341
+ are accepted, but these are for backward compatibility only and should
2342
+ not be used in new code.
2343
+
2344
+ Examples
2345
+ --------
2346
+ Import the necessary modules and load the example image used for
2347
+ filtering.
2348
+
2349
+ >>> import numpy as np
2350
+ >>> from scipy import datasets
2351
+ >>> from scipy.ndimage import zoom, generic_filter
2352
+ >>> import matplotlib.pyplot as plt
2353
+ >>> ascent = zoom(datasets.ascent(), 0.5)
2354
+
2355
+ Compute a maximum filter with kernel size 5 by passing a simple NumPy
2356
+ aggregation function as argument to `function`.
2357
+
2358
+ >>> maximum_filter_result = generic_filter(ascent, np.amax, [5, 5])
2359
+
2360
+ While a maximum filter could also directly be obtained using
2361
+ `maximum_filter`, `generic_filter` allows generic Python function or
2362
+ `scipy.LowLevelCallable` to be used as a filter. Here, we compute the
2363
+ range between maximum and minimum value as an example for a kernel size
2364
+ of 5.
2365
+
2366
+ >>> def custom_filter(image):
2367
+ ... return np.amax(image) - np.amin(image)
2368
+ >>> custom_filter_result = generic_filter(ascent, custom_filter, [5, 5])
2369
+
2370
+ Plot the original and filtered images.
2371
+
2372
+ >>> fig, axes = plt.subplots(3, 1, figsize=(3, 9))
2373
+ >>> plt.gray() # show the filtered result in grayscale
2374
+ >>> top, middle, bottom = axes
2375
+ >>> for ax in axes:
2376
+ ... ax.set_axis_off() # remove coordinate system
2377
+ >>> top.imshow(ascent)
2378
+ >>> top.set_title("Original image")
2379
+ >>> middle.imshow(maximum_filter_result)
2380
+ >>> middle.set_title("Maximum filter, Kernel: 5x5")
2381
+ >>> bottom.imshow(custom_filter_result)
2382
+ >>> bottom.set_title("Custom filter, Kernel: 5x5")
2383
+ >>> fig.tight_layout()
2384
+
2385
+ """
2386
+ if (size is not None) and (footprint is not None):
2387
+ warnings.warn("ignoring size because footprint is set",
2388
+ UserWarning, stacklevel=2)
2389
+ if extra_keywords is None:
2390
+ extra_keywords = {}
2391
+ input = np.asarray(input)
2392
+ if np.iscomplexobj(input):
2393
+ raise TypeError('Complex type not supported')
2394
+ axes = _ni_support._check_axes(axes, input.ndim)
2395
+ num_axes = len(axes)
2396
+ if footprint is None:
2397
+ if size is None:
2398
+ raise RuntimeError("no footprint or filter size provided")
2399
+ sizes = _ni_support._normalize_sequence(size, num_axes)
2400
+ footprint = np.ones(sizes, dtype=bool)
2401
+ else:
2402
+ footprint = np.asarray(footprint, dtype=bool)
2403
+
2404
+ # expand origins, footprint if num_axes < input.ndim
2405
+ footprint = _expand_footprint(input.ndim, axes, footprint)
2406
+ origins = _expand_origin(input.ndim, axes, origin)
2407
+
2408
+ fshape = [ii for ii in footprint.shape if ii > 0]
2409
+ if len(fshape) != input.ndim:
2410
+ raise RuntimeError(f"footprint.ndim ({footprint.ndim}) "
2411
+ f"must match len(axes) ({num_axes})")
2412
+ for origin, lenf in zip(origins, fshape):
2413
+ if (lenf // 2 + origin < 0) or (lenf // 2 + origin >= lenf):
2414
+ raise ValueError('invalid origin')
2415
+ if not footprint.flags.contiguous:
2416
+ footprint = footprint.copy()
2417
+ output = _ni_support._get_output(output, input)
2418
+
2419
+ mode = _ni_support._extend_mode_to_code(mode)
2420
+ _nd_image.generic_filter(input, function, footprint, output, mode,
2421
+ cval, origins, extra_arguments, extra_keywords)
2422
+ return output