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,1458 @@
1
+ """Functions for FIR filter design."""
2
+
3
+ from math import ceil, log, log2
4
+ import warnings
5
+ from typing import Literal
6
+
7
+ import numpy as np
8
+ from scipy.fft import irfft, fft, ifft
9
+ from scipy.linalg import (toeplitz, hankel, solve, LinAlgError, LinAlgWarning,
10
+ lstsq)
11
+ from scipy.signal._arraytools import _validate_fs
12
+
13
+ from . import _sigtools
14
+
15
+ from scipy._lib._array_api import array_namespace, xp_size, xp_default_dtype
16
+ import scipy._lib.array_api_extra as xpx
17
+
18
+
19
+ __all__ = ['kaiser_beta', 'kaiser_atten', 'kaiserord',
20
+ 'firwin', 'firwin2', 'firwin_2d', 'remez', 'firls', 'minimum_phase']
21
+
22
+
23
+ # Some notes on function parameters:
24
+ #
25
+ # `cutoff` and `width` are given as numbers between 0 and 1. These are
26
+ # relative frequencies, expressed as a fraction of the Nyquist frequency.
27
+ # For example, if the Nyquist frequency is 2 KHz, then width=0.15 is a width
28
+ # of 300 Hz.
29
+ #
30
+ # The `order` of a FIR filter is one less than the number of taps.
31
+ # This is a potential source of confusion, so in the following code,
32
+ # we will always use the number of taps as the parameterization of
33
+ # the 'size' of the filter. The "number of taps" means the number
34
+ # of coefficients, which is the same as the length of the impulse
35
+ # response of the filter.
36
+
37
+
38
+ def kaiser_beta(a):
39
+ """Compute the Kaiser parameter `beta`, given the attenuation `a`.
40
+
41
+ Parameters
42
+ ----------
43
+ a : float
44
+ The desired attenuation in the stopband and maximum ripple in
45
+ the passband, in dB. This should be a *positive* number.
46
+
47
+ Returns
48
+ -------
49
+ beta : float
50
+ The `beta` parameter to be used in the formula for a Kaiser window.
51
+
52
+ References
53
+ ----------
54
+ Oppenheim, Schafer, "Discrete-Time Signal Processing", p.475-476.
55
+
56
+ Examples
57
+ --------
58
+ Suppose we want to design a lowpass filter, with 65 dB attenuation
59
+ in the stop band. The Kaiser window parameter to be used in the
60
+ window method is computed by ``kaiser_beta(65)``:
61
+
62
+ >>> from scipy.signal import kaiser_beta
63
+ >>> kaiser_beta(65)
64
+ 6.20426
65
+
66
+ """
67
+ if a > 50:
68
+ beta = 0.1102 * (a - 8.7)
69
+ elif a > 21:
70
+ beta = 0.5842 * (a - 21) ** 0.4 + 0.07886 * (a - 21)
71
+ else:
72
+ beta = 0.0
73
+ return beta
74
+
75
+
76
+ def kaiser_atten(numtaps, width):
77
+ """Compute the attenuation of a Kaiser FIR filter.
78
+
79
+ Given the number of taps `N` and the transition width `width`, compute the
80
+ attenuation `a` in dB, given by Kaiser's formula:
81
+
82
+ a = 2.285 * (N - 1) * pi * width + 7.95
83
+
84
+ Parameters
85
+ ----------
86
+ numtaps : int
87
+ The number of taps in the FIR filter.
88
+ width : float
89
+ The desired width of the transition region between passband and
90
+ stopband (or, in general, at any discontinuity) for the filter,
91
+ expressed as a fraction of the Nyquist frequency.
92
+
93
+ Returns
94
+ -------
95
+ a : float
96
+ The attenuation of the ripple, in dB.
97
+
98
+ See Also
99
+ --------
100
+ kaiserord, kaiser_beta
101
+
102
+ Examples
103
+ --------
104
+ Suppose we want to design a FIR filter using the Kaiser window method
105
+ that will have 211 taps and a transition width of 9 Hz for a signal that
106
+ is sampled at 480 Hz. Expressed as a fraction of the Nyquist frequency,
107
+ the width is 9/(0.5*480) = 0.0375. The approximate attenuation (in dB)
108
+ is computed as follows:
109
+
110
+ >>> from scipy.signal import kaiser_atten
111
+ >>> kaiser_atten(211, 0.0375)
112
+ 64.48099630593983
113
+
114
+ """
115
+ a = 2.285 * (numtaps - 1) * np.pi * width + 7.95
116
+ return a
117
+
118
+
119
+ def kaiserord(ripple, width):
120
+ """
121
+ Determine the filter window parameters for the Kaiser window method.
122
+
123
+ The parameters returned by this function are generally used to create
124
+ a finite impulse response filter using the window method, with either
125
+ `firwin` or `firwin2`.
126
+
127
+ Parameters
128
+ ----------
129
+ ripple : float
130
+ Upper bound for the deviation (in dB) of the magnitude of the
131
+ filter's frequency response from that of the desired filter (not
132
+ including frequencies in any transition intervals). That is, if w
133
+ is the frequency expressed as a fraction of the Nyquist frequency,
134
+ A(w) is the actual frequency response of the filter and D(w) is the
135
+ desired frequency response, the design requirement is that::
136
+
137
+ abs(A(w) - D(w))) < 10**(-ripple/20)
138
+
139
+ for 0 <= w <= 1 and w not in a transition interval.
140
+ width : float
141
+ Width of transition region, normalized so that 1 corresponds to pi
142
+ radians / sample. That is, the frequency is expressed as a fraction
143
+ of the Nyquist frequency.
144
+
145
+ Returns
146
+ -------
147
+ numtaps : int
148
+ The length of the Kaiser window.
149
+ beta : float
150
+ The beta parameter for the Kaiser window.
151
+
152
+ See Also
153
+ --------
154
+ kaiser_beta, kaiser_atten
155
+
156
+ Notes
157
+ -----
158
+ There are several ways to obtain the Kaiser window:
159
+
160
+ - ``signal.windows.kaiser(numtaps, beta, sym=True)``
161
+ - ``signal.get_window(beta, numtaps)``
162
+ - ``signal.get_window(('kaiser', beta), numtaps)``
163
+
164
+ The empirical equations discovered by Kaiser are used.
165
+
166
+ References
167
+ ----------
168
+ Oppenheim, Schafer, "Discrete-Time Signal Processing", pp.475-476.
169
+
170
+ Examples
171
+ --------
172
+ We will use the Kaiser window method to design a lowpass FIR filter
173
+ for a signal that is sampled at 1000 Hz.
174
+
175
+ We want at least 65 dB rejection in the stop band, and in the pass
176
+ band the gain should vary no more than 0.5%.
177
+
178
+ We want a cutoff frequency of 175 Hz, with a transition between the
179
+ pass band and the stop band of 24 Hz. That is, in the band [0, 163],
180
+ the gain varies no more than 0.5%, and in the band [187, 500], the
181
+ signal is attenuated by at least 65 dB.
182
+
183
+ >>> import numpy as np
184
+ >>> from scipy.signal import kaiserord, firwin, freqz
185
+ >>> import matplotlib.pyplot as plt
186
+ >>> fs = 1000.0
187
+ >>> cutoff = 175
188
+ >>> width = 24
189
+
190
+ The Kaiser method accepts just a single parameter to control the pass
191
+ band ripple and the stop band rejection, so we use the more restrictive
192
+ of the two. In this case, the pass band ripple is 0.005, or 46.02 dB,
193
+ so we will use 65 dB as the design parameter.
194
+
195
+ Use `kaiserord` to determine the length of the filter and the
196
+ parameter for the Kaiser window.
197
+
198
+ >>> numtaps, beta = kaiserord(65, width/(0.5*fs))
199
+ >>> numtaps
200
+ 167
201
+ >>> beta
202
+ 6.20426
203
+
204
+ Use `firwin` to create the FIR filter.
205
+
206
+ >>> taps = firwin(numtaps, cutoff, window=('kaiser', beta),
207
+ ... scale=False, fs=fs)
208
+
209
+ Compute the frequency response of the filter. ``w`` is the array of
210
+ frequencies, and ``h`` is the corresponding complex array of frequency
211
+ responses.
212
+
213
+ >>> w, h = freqz(taps, worN=8000)
214
+ >>> w *= 0.5*fs/np.pi # Convert w to Hz.
215
+
216
+ Compute the deviation of the magnitude of the filter's response from
217
+ that of the ideal lowpass filter. Values in the transition region are
218
+ set to ``nan``, so they won't appear in the plot.
219
+
220
+ >>> ideal = w < cutoff # The "ideal" frequency response.
221
+ >>> deviation = np.abs(np.abs(h) - ideal)
222
+ >>> deviation[(w > cutoff - 0.5*width) & (w < cutoff + 0.5*width)] = np.nan
223
+
224
+ Plot the deviation. A close look at the left end of the stop band shows
225
+ that the requirement for 65 dB attenuation is violated in the first lobe
226
+ by about 0.125 dB. This is not unusual for the Kaiser window method.
227
+
228
+ >>> plt.plot(w, 20*np.log10(np.abs(deviation)))
229
+ >>> plt.xlim(0, 0.5*fs)
230
+ >>> plt.ylim(-90, -60)
231
+ >>> plt.grid(alpha=0.25)
232
+ >>> plt.axhline(-65, color='r', ls='--', alpha=0.3)
233
+ >>> plt.xlabel('Frequency (Hz)')
234
+ >>> plt.ylabel('Deviation from ideal (dB)')
235
+ >>> plt.title('Lowpass Filter Frequency Response')
236
+ >>> plt.show()
237
+
238
+ """
239
+ A = abs(ripple) # in case somebody is confused as to what's meant
240
+ if A < 8:
241
+ # Formula for N is not valid in this range.
242
+ raise ValueError("Requested maximum ripple attenuation "
243
+ f"{A:f} is too small for the Kaiser formula.")
244
+ beta = kaiser_beta(A)
245
+
246
+ # Kaiser's formula (as given in Oppenheim and Schafer) is for the filter
247
+ # order, so we have to add 1 to get the number of taps.
248
+ numtaps = (A - 7.95) / 2.285 / (np.pi * width) + 1
249
+
250
+ return int(ceil(numtaps)), beta
251
+
252
+
253
+ def firwin(numtaps, cutoff, *, width=None, window='hamming', pass_zero=True,
254
+ scale=True, fs=None):
255
+ """
256
+ FIR filter design using the window method.
257
+
258
+ This function computes the coefficients of a finite impulse response
259
+ filter. The filter will have linear phase; it will be Type I if
260
+ `numtaps` is odd and Type II if `numtaps` is even.
261
+
262
+ Type II filters always have zero response at the Nyquist frequency, so a
263
+ ValueError exception is raised if firwin is called with `numtaps` even and
264
+ having a passband whose right end is at the Nyquist frequency.
265
+
266
+ Parameters
267
+ ----------
268
+ numtaps : int
269
+ Length of the filter (number of coefficients, i.e. the filter
270
+ order + 1). `numtaps` must be odd if a passband includes the
271
+ Nyquist frequency.
272
+ cutoff : float or 1-D array_like
273
+ Cutoff frequency of filter (expressed in the same units as `fs`)
274
+ OR an array of cutoff frequencies (that is, band edges). In the
275
+ former case, as a float, the cutoff frequency should correspond
276
+ with the half-amplitude point, where the attenuation will be -6dB.
277
+ In the latter case, the frequencies in `cutoff` should be positive
278
+ and monotonically increasing between 0 and `fs/2`. The values 0
279
+ and `fs/2` must not be included in `cutoff`. It should be noted
280
+ that this is different than the behavior of `scipy.signal.iirdesign`,
281
+ where the cutoff is the half-power point (-3dB).
282
+ width : float or None, optional
283
+ If `width` is not None, then assume it is the approximate width
284
+ of the transition region (expressed in the same units as `fs`)
285
+ for use in Kaiser FIR filter design. In this case, the `window`
286
+ argument is ignored.
287
+ window : string or tuple of string and parameter values, optional
288
+ Desired window to use. See `scipy.signal.get_window` for a list
289
+ of windows and required parameters.
290
+ pass_zero : {True, False, 'bandpass', 'lowpass', 'highpass', 'bandstop'}, optional
291
+ If True, the gain at the frequency 0 (i.e., the "DC gain") is 1.
292
+ If False, the DC gain is 0. Can also be a string argument for the
293
+ desired filter type (equivalent to ``btype`` in IIR design functions).
294
+
295
+ .. versionadded:: 1.3.0
296
+ Support for string arguments.
297
+ scale : bool, optional
298
+ Set to True to scale the coefficients so that the frequency
299
+ response is exactly unity at a certain frequency.
300
+ That frequency is either:
301
+
302
+ - 0 (DC) if the first passband starts at 0 (i.e. pass_zero
303
+ is True)
304
+ - `fs/2` (the Nyquist frequency) if the first passband ends at
305
+ `fs/2` (i.e the filter is a single band highpass filter);
306
+ center of first passband otherwise
307
+
308
+ fs : float, optional
309
+ The sampling frequency of the signal. Each frequency in `cutoff`
310
+ must be between 0 and ``fs/2``. Default is 2.
311
+
312
+ Returns
313
+ -------
314
+ h : (numtaps,) ndarray
315
+ Coefficients of length `numtaps` FIR filter.
316
+
317
+ Raises
318
+ ------
319
+ ValueError
320
+ If any value in `cutoff` is less than or equal to 0 or greater
321
+ than or equal to ``fs/2``, if the values in `cutoff` are not strictly
322
+ monotonically increasing, or if `numtaps` is even but a passband
323
+ includes the Nyquist frequency.
324
+
325
+ See Also
326
+ --------
327
+ firwin2
328
+ firwin_2d
329
+ firls
330
+ minimum_phase
331
+ remez
332
+
333
+ Examples
334
+ --------
335
+ Low-pass from 0 to f:
336
+
337
+ >>> from scipy import signal
338
+ >>> numtaps = 3
339
+ >>> f = 0.1
340
+ >>> signal.firwin(numtaps, f)
341
+ array([ 0.06799017, 0.86401967, 0.06799017])
342
+
343
+ Use a specific window function:
344
+
345
+ >>> signal.firwin(numtaps, f, window='nuttall')
346
+ array([ 3.56607041e-04, 9.99286786e-01, 3.56607041e-04])
347
+
348
+ High-pass ('stop' from 0 to f):
349
+
350
+ >>> signal.firwin(numtaps, f, pass_zero=False)
351
+ array([-0.00859313, 0.98281375, -0.00859313])
352
+
353
+ Band-pass:
354
+
355
+ >>> f1, f2 = 0.1, 0.2
356
+ >>> signal.firwin(numtaps, [f1, f2], pass_zero=False)
357
+ array([ 0.06301614, 0.88770441, 0.06301614])
358
+
359
+ Band-stop:
360
+
361
+ >>> signal.firwin(numtaps, [f1, f2])
362
+ array([-0.00801395, 1.0160279 , -0.00801395])
363
+
364
+ Multi-band (passbands are [0, f1], [f2, f3] and [f4, 1]):
365
+
366
+ >>> f3, f4 = 0.3, 0.4
367
+ >>> signal.firwin(numtaps, [f1, f2, f3, f4])
368
+ array([-0.01376344, 1.02752689, -0.01376344])
369
+
370
+ Multi-band (passbands are [f1, f2] and [f3,f4]):
371
+
372
+ >>> signal.firwin(numtaps, [f1, f2, f3, f4], pass_zero=False)
373
+ array([ 0.04890915, 0.91284326, 0.04890915])
374
+
375
+ """
376
+ # NB: scipy's version of array_namespace returns `np_compat` for int or floats
377
+ xp = array_namespace(cutoff)
378
+
379
+ # The major enhancements to this function added in November 2010 were
380
+ # developed by Tom Krauss (see ticket #902).
381
+ fs = _validate_fs(fs, allow_none=True)
382
+ fs = 2 if fs is None else fs
383
+
384
+ nyq = 0.5 * fs
385
+
386
+ cutoff = xp.asarray(cutoff, dtype=xp_default_dtype(xp))
387
+ cutoff = xpx.atleast_nd(cutoff, ndim=1, xp=xp) / float(nyq)
388
+
389
+ # Check for invalid input.
390
+ if cutoff.ndim > 1:
391
+ raise ValueError("The cutoff argument must be at most "
392
+ "one-dimensional.")
393
+ if xp_size(cutoff) == 0:
394
+ raise ValueError("At least one cutoff frequency must be given.")
395
+ if xp.min(cutoff) <= 0 or xp.max(cutoff) >= 1:
396
+ raise ValueError("Invalid cutoff frequency: frequencies must be "
397
+ "greater than 0 and less than fs/2.")
398
+ if xp.any(cutoff[1:] - cutoff[:-1] <= 0):
399
+ raise ValueError("Invalid cutoff frequencies: the frequencies "
400
+ "must be strictly increasing.")
401
+
402
+ if width is not None:
403
+ # A width was given. Find the beta parameter of the Kaiser window
404
+ # and set `window`. This overrides the value of `window` passed in.
405
+ atten = kaiser_atten(numtaps, float(width) / nyq)
406
+ beta = kaiser_beta(atten)
407
+ window = ('kaiser', beta)
408
+
409
+ if pass_zero in ('bandstop', 'lowpass'):
410
+ if pass_zero == 'lowpass':
411
+ if xp_size(cutoff) != 1:
412
+ raise ValueError('cutoff must have one element if '
413
+ f'pass_zero=="lowpass", got {cutoff.shape}')
414
+ elif xp_size(cutoff) <= 1:
415
+ raise ValueError('cutoff must have at least two elements if '
416
+ f'pass_zero=="bandstop", got {cutoff.shape}')
417
+ pass_zero = True
418
+ elif pass_zero in ('bandpass', 'highpass'):
419
+ if pass_zero == 'highpass':
420
+ if xp_size(cutoff) != 1:
421
+ raise ValueError('cutoff must have one element if '
422
+ f'pass_zero=="highpass", got {cutoff.shape}')
423
+ elif xp_size(cutoff) <= 1:
424
+ raise ValueError('cutoff must have at least two elements if '
425
+ f'pass_zero=="bandpass", got {cutoff.shape}')
426
+ pass_zero = False
427
+ elif not (pass_zero is True or pass_zero is False):
428
+ raise ValueError(f"Parameter {pass_zero=} not in (True, False, 'bandpass', " +
429
+ "'lowpass', 'highpass', 'bandstop')")
430
+
431
+ pass_nyquist = (xp_size(cutoff) % 2 == 0) == pass_zero
432
+ if pass_nyquist and numtaps % 2 == 0:
433
+ raise ValueError("A filter with an even number of coefficients must "
434
+ "have zero response at the Nyquist frequency.")
435
+
436
+ # Insert 0 and/or 1 at the ends of cutoff so that the length of cutoff
437
+ # is even, and each pair in cutoff corresponds to passband.
438
+ cutoff = xp.concat((xp.zeros(int(pass_zero)), cutoff, xp.ones(int(pass_nyquist))))
439
+
440
+
441
+ # `bands` is a 2-D array; each row gives the left and right edges of
442
+ # a passband.
443
+ bands = xp.reshape(cutoff, (-1, 2))
444
+
445
+ # Build up the coefficients.
446
+ alpha = 0.5 * (numtaps - 1)
447
+ m = xp.arange(0, numtaps, dtype=cutoff.dtype) - alpha
448
+ h = 0
449
+ for j in range(bands.shape[0]):
450
+ left, right = bands[j, 0], bands[j, 1]
451
+ h += right * xpx.sinc(right * m, xp=xp)
452
+ h -= left * xpx.sinc(left * m, xp=xp)
453
+
454
+ # Get and apply the window function.
455
+ from .windows import get_window
456
+ win = get_window(window, numtaps, fftbins=False, xp=xp)
457
+ h *= win
458
+
459
+ # Now handle scaling if desired.
460
+ if scale:
461
+ # Get the first passband.
462
+ left, right = bands[0, ...]
463
+ if left == 0:
464
+ scale_frequency = 0.0
465
+ elif right == 1:
466
+ scale_frequency = 1.0
467
+ else:
468
+ scale_frequency = 0.5 * (left + right)
469
+ c = xp.cos(xp.pi * m * scale_frequency)
470
+ s = xp.sum(h * c)
471
+ h /= s
472
+
473
+ return h
474
+
475
+
476
+ # Original version of firwin2 from scipy ticket #457, submitted by "tash".
477
+ #
478
+ # Rewritten by Warren Weckesser, 2010.
479
+ def firwin2(numtaps, freq, gain, *, nfreqs=None, window='hamming',
480
+ antisymmetric=False, fs=None):
481
+ """
482
+ FIR filter design using the window method.
483
+
484
+ From the given frequencies `freq` and corresponding gains `gain`,
485
+ this function constructs an FIR filter with linear phase and
486
+ (approximately) the given frequency response.
487
+
488
+ Parameters
489
+ ----------
490
+ numtaps : int
491
+ The number of taps in the FIR filter. `numtaps` must be less than
492
+ `nfreqs`.
493
+ freq : array_like, 1-D
494
+ The frequency sampling points. Typically 0.0 to 1.0 with 1.0 being
495
+ Nyquist. The Nyquist frequency is half `fs`.
496
+ The values in `freq` must be nondecreasing. A value can be repeated
497
+ once to implement a discontinuity. The first value in `freq` must
498
+ be 0, and the last value must be ``fs/2``. Values 0 and ``fs/2`` must
499
+ not be repeated.
500
+ gain : array_like
501
+ The filter gains at the frequency sampling points. Certain
502
+ constraints to gain values, depending on the filter type, are applied,
503
+ see Notes for details.
504
+ nfreqs : int, optional
505
+ The size of the interpolation mesh used to construct the filter.
506
+ For most efficient behavior, this should be a power of 2 plus 1
507
+ (e.g, 129, 257, etc). The default is one more than the smallest
508
+ power of 2 that is not less than `numtaps`. `nfreqs` must be greater
509
+ than `numtaps`.
510
+ window : string or (string, float) or float, or None, optional
511
+ Window function to use. Default is "hamming". See
512
+ `scipy.signal.get_window` for the complete list of possible values.
513
+ If None, no window function is applied.
514
+ antisymmetric : bool, optional
515
+ Whether resulting impulse response is symmetric/antisymmetric.
516
+ See Notes for more details.
517
+ fs : float, optional
518
+ The sampling frequency of the signal. Each frequency in `cutoff`
519
+ must be between 0 and ``fs/2``. Default is 2.
520
+
521
+ Returns
522
+ -------
523
+ taps : ndarray
524
+ The filter coefficients of the FIR filter, as a 1-D array of length
525
+ `numtaps`.
526
+
527
+ See Also
528
+ --------
529
+ firls
530
+ firwin
531
+ minimum_phase
532
+ remez
533
+
534
+ Notes
535
+ -----
536
+ From the given set of frequencies and gains, the desired response is
537
+ constructed in the frequency domain. The inverse FFT is applied to the
538
+ desired response to create the associated convolution kernel, and the
539
+ first `numtaps` coefficients of this kernel, scaled by `window`, are
540
+ returned.
541
+
542
+ The FIR filter will have linear phase. The type of filter is determined by
543
+ the value of 'numtaps` and `antisymmetric` flag.
544
+ There are four possible combinations:
545
+
546
+ - odd `numtaps`, `antisymmetric` is False, type I filter is produced
547
+ - even `numtaps`, `antisymmetric` is False, type II filter is produced
548
+ - odd `numtaps`, `antisymmetric` is True, type III filter is produced
549
+ - even `numtaps`, `antisymmetric` is True, type IV filter is produced
550
+
551
+ Magnitude response of all but type I filters are subjects to following
552
+ constraints:
553
+
554
+ - type II -- zero at the Nyquist frequency
555
+ - type III -- zero at zero and Nyquist frequencies
556
+ - type IV -- zero at zero frequency
557
+
558
+ .. versionadded:: 0.9.0
559
+
560
+ References
561
+ ----------
562
+ .. [1] Oppenheim, A. V. and Schafer, R. W., "Discrete-Time Signal
563
+ Processing", Prentice-Hall, Englewood Cliffs, New Jersey (1989).
564
+ (See, for example, Section 7.4.)
565
+
566
+ .. [2] Smith, Steven W., "The Scientist and Engineer's Guide to Digital
567
+ Signal Processing", Ch. 17. http://www.dspguide.com/ch17/1.htm
568
+
569
+ Examples
570
+ --------
571
+ A lowpass FIR filter with a response that is 1 on [0.0, 0.5], and
572
+ that decreases linearly on [0.5, 1.0] from 1 to 0:
573
+
574
+ >>> from scipy import signal
575
+ >>> taps = signal.firwin2(150, [0.0, 0.5, 1.0], [1.0, 1.0, 0.0])
576
+ >>> print(taps[72:78])
577
+ [-0.02286961 -0.06362756 0.57310236 0.57310236 -0.06362756 -0.02286961]
578
+
579
+ """
580
+ xp = array_namespace(freq, gain)
581
+ freq, gain = xp.asarray(freq), xp.asarray(gain)
582
+
583
+ fs = _validate_fs(fs, allow_none=True)
584
+ fs = 2 if fs is None else fs
585
+ nyq = 0.5 * fs
586
+
587
+ if freq.shape[0] != gain.shape[0]:
588
+ raise ValueError('freq and gain must be of same length.')
589
+
590
+ if nfreqs is not None and numtaps >= nfreqs:
591
+ raise ValueError(
592
+ f'ntaps must be less than nfreqs, but firwin2 was called with '
593
+ f'ntaps={numtaps} and nfreqs={nfreqs}'
594
+ )
595
+
596
+ if freq[0] != 0 or freq[-1] != nyq:
597
+ raise ValueError('freq must start with 0 and end with fs/2.')
598
+ d = freq[1:] - freq[:-1]
599
+ if xp.any(d < 0):
600
+ raise ValueError('The values in freq must be nondecreasing.')
601
+ d2 = d[:-1] + d[1:]
602
+ if xp.any(d2 == 0):
603
+ raise ValueError('A value in freq must not occur more than twice.')
604
+ if freq[1] == 0:
605
+ raise ValueError('Value 0 must not be repeated in freq')
606
+ if freq[-2] == nyq:
607
+ raise ValueError('Value fs/2 must not be repeated in freq')
608
+
609
+ if antisymmetric:
610
+ if numtaps % 2 == 0:
611
+ ftype = 4
612
+ else:
613
+ ftype = 3
614
+ else:
615
+ if numtaps % 2 == 0:
616
+ ftype = 2
617
+ else:
618
+ ftype = 1
619
+
620
+ if ftype == 2 and gain[-1] != 0.0:
621
+ raise ValueError("A Type II filter must have zero gain at the "
622
+ "Nyquist frequency.")
623
+ elif ftype == 3 and (gain[0] != 0.0 or gain[-1] != 0.0):
624
+ raise ValueError("A Type III filter must have zero gain at zero "
625
+ "and Nyquist frequencies.")
626
+ elif ftype == 4 and gain[0] != 0.0:
627
+ raise ValueError("A Type IV filter must have zero gain at zero "
628
+ "frequency.")
629
+
630
+ if nfreqs is None:
631
+ nfreqs = 1 + 2 ** int(ceil(log(numtaps, 2)))
632
+
633
+ if xp.any(d == 0):
634
+ # Tweak any repeated values in freq so that interp works.
635
+ freq = xp.asarray(freq, copy=True)
636
+ eps = xp.finfo(xp_default_dtype(xp)).eps * nyq
637
+ for k in range(freq.shape[0] - 1):
638
+ if freq[k] == freq[k + 1]:
639
+ freq[k] = freq[k] - eps
640
+ freq[k + 1] = freq[k + 1] + eps
641
+ # Check if freq is strictly increasing after tweak
642
+ d = freq[1:] - freq[:-1]
643
+ if xp.any(d <= 0):
644
+ raise ValueError("freq cannot contain numbers that are too close "
645
+ "(within eps * (fs/2): "
646
+ f"{eps}) to a repeated value")
647
+
648
+ # Linearly interpolate the desired response on a uniform mesh `x`.
649
+ x = np.linspace(0.0, nyq, nfreqs)
650
+ fx = np.interp(x, np.asarray(freq), np.asarray(gain)) # XXX array-api-extra#193
651
+ x = xp.asarray(x)
652
+ fx = xp.asarray(fx)
653
+
654
+ # Adjust the phases of the coefficients so that the first `ntaps` of the
655
+ # inverse FFT are the desired filter coefficients.
656
+ shift = xp.exp(-(numtaps - 1) / 2. * 1j * xp.pi * x / nyq)
657
+ if ftype > 2:
658
+ shift *= 1j
659
+
660
+ fx2 = fx * shift
661
+
662
+ # Use irfft to compute the inverse FFT.
663
+ out_full = irfft(fx2)
664
+
665
+ if window is not None:
666
+ # Create the window to apply to the filter coefficients.
667
+ from .windows import get_window
668
+ wind = get_window(window, numtaps, fftbins=False, xp=xp)
669
+ else:
670
+ wind = 1
671
+
672
+ # Keep only the first `numtaps` coefficients in `out`, and multiply by
673
+ # the window.
674
+ out = out_full[:numtaps] * wind
675
+
676
+ if ftype == 3:
677
+ out[xp_size(out) // 2] = 0.0
678
+
679
+ return out
680
+
681
+
682
+ def remez(numtaps, bands, desired, *, weight=None, type='bandpass',
683
+ maxiter=25, grid_density=16, fs=None):
684
+ """
685
+ Calculate the minimax optimal filter using the Remez exchange algorithm.
686
+
687
+ Calculate the filter-coefficients for the finite impulse response
688
+ (FIR) filter whose transfer function minimizes the maximum error
689
+ between the desired gain and the realized gain in the specified
690
+ frequency bands using the Remez exchange algorithm.
691
+
692
+ Parameters
693
+ ----------
694
+ numtaps : int
695
+ The desired number of taps in the filter. The number of taps is
696
+ the number of terms in the filter, or the filter order plus one.
697
+ bands : array_like
698
+ A monotonic sequence containing the band edges.
699
+ All elements must be non-negative and less than half the sampling
700
+ frequency as given by `fs`.
701
+ desired : array_like
702
+ A sequence half the size of bands containing the desired gain
703
+ in each of the specified bands.
704
+ weight : array_like, optional
705
+ A relative weighting to give to each band region. The length of
706
+ `weight` has to be half the length of `bands`.
707
+ type : {'bandpass', 'differentiator', 'hilbert'}, optional
708
+ The type of filter:
709
+
710
+ * 'bandpass' : flat response in bands. This is the default.
711
+
712
+ * 'differentiator' : frequency proportional response in bands.
713
+
714
+ * 'hilbert' : filter with odd symmetry, that is, type III
715
+ (for even order) or type IV (for odd order)
716
+ linear phase filters.
717
+
718
+ maxiter : int, optional
719
+ Maximum number of iterations of the algorithm. Default is 25.
720
+ grid_density : int, optional
721
+ Grid density. The dense grid used in `remez` is of size
722
+ ``(numtaps + 1) * grid_density``. Default is 16.
723
+ fs : float, optional
724
+ The sampling frequency of the signal. Default is 1.
725
+
726
+ Returns
727
+ -------
728
+ out : ndarray
729
+ A rank-1 array containing the coefficients of the optimal
730
+ (in a minimax sense) filter.
731
+
732
+ See Also
733
+ --------
734
+ firls
735
+ firwin
736
+ firwin2
737
+ minimum_phase
738
+
739
+ References
740
+ ----------
741
+ .. [1] J. H. McClellan and T. W. Parks, "A unified approach to the
742
+ design of optimum FIR linear phase digital filters",
743
+ IEEE Trans. Circuit Theory, vol. CT-20, pp. 697-701, 1973.
744
+ .. [2] J. H. McClellan, T. W. Parks and L. R. Rabiner, "A Computer
745
+ Program for Designing Optimum FIR Linear Phase Digital
746
+ Filters", IEEE Trans. Audio Electroacoust., vol. AU-21,
747
+ pp. 506-525, 1973.
748
+
749
+ Examples
750
+ --------
751
+ In these examples, `remez` is used to design low-pass, high-pass,
752
+ band-pass and band-stop filters. The parameters that define each filter
753
+ are the filter order, the band boundaries, the transition widths of the
754
+ boundaries, the desired gains in each band, and the sampling frequency.
755
+
756
+ We'll use a sample frequency of 22050 Hz in all the examples. In each
757
+ example, the desired gain in each band is either 0 (for a stop band)
758
+ or 1 (for a pass band).
759
+
760
+ `freqz` is used to compute the frequency response of each filter, and
761
+ the utility function ``plot_response`` defined below is used to plot
762
+ the response.
763
+
764
+ >>> import numpy as np
765
+ >>> from scipy import signal
766
+ >>> import matplotlib.pyplot as plt
767
+
768
+ >>> fs = 22050 # Sample rate, Hz
769
+
770
+ >>> def plot_response(w, h, title):
771
+ ... "Utility function to plot response functions"
772
+ ... fig = plt.figure()
773
+ ... ax = fig.add_subplot(111)
774
+ ... ax.plot(w, 20*np.log10(np.abs(h)))
775
+ ... ax.set_ylim(-40, 5)
776
+ ... ax.grid(True)
777
+ ... ax.set_xlabel('Frequency (Hz)')
778
+ ... ax.set_ylabel('Gain (dB)')
779
+ ... ax.set_title(title)
780
+
781
+ The first example is a low-pass filter, with cutoff frequency 8 kHz.
782
+ The filter length is 325, and the transition width from pass to stop
783
+ is 100 Hz.
784
+
785
+ >>> cutoff = 8000.0 # Desired cutoff frequency, Hz
786
+ >>> trans_width = 100 # Width of transition from pass to stop, Hz
787
+ >>> numtaps = 325 # Size of the FIR filter.
788
+ >>> taps = signal.remez(numtaps, [0, cutoff, cutoff + trans_width, 0.5*fs],
789
+ ... [1, 0], fs=fs)
790
+ >>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
791
+ >>> plot_response(w, h, "Low-pass Filter")
792
+ >>> plt.show()
793
+
794
+ This example shows a high-pass filter:
795
+
796
+ >>> cutoff = 2000.0 # Desired cutoff frequency, Hz
797
+ >>> trans_width = 250 # Width of transition from pass to stop, Hz
798
+ >>> numtaps = 125 # Size of the FIR filter.
799
+ >>> taps = signal.remez(numtaps, [0, cutoff - trans_width, cutoff, 0.5*fs],
800
+ ... [0, 1], fs=fs)
801
+ >>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
802
+ >>> plot_response(w, h, "High-pass Filter")
803
+ >>> plt.show()
804
+
805
+ This example shows a band-pass filter with a pass-band from 2 kHz to
806
+ 5 kHz. The transition width is 260 Hz and the length of the filter
807
+ is 63, which is smaller than in the other examples:
808
+
809
+ >>> band = [2000, 5000] # Desired pass band, Hz
810
+ >>> trans_width = 260 # Width of transition from pass to stop, Hz
811
+ >>> numtaps = 63 # Size of the FIR filter.
812
+ >>> edges = [0, band[0] - trans_width, band[0], band[1],
813
+ ... band[1] + trans_width, 0.5*fs]
814
+ >>> taps = signal.remez(numtaps, edges, [0, 1, 0], fs=fs)
815
+ >>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
816
+ >>> plot_response(w, h, "Band-pass Filter")
817
+ >>> plt.show()
818
+
819
+ The low order leads to higher ripple and less steep transitions.
820
+
821
+ The next example shows a band-stop filter.
822
+
823
+ >>> band = [6000, 8000] # Desired stop band, Hz
824
+ >>> trans_width = 200 # Width of transition from pass to stop, Hz
825
+ >>> numtaps = 175 # Size of the FIR filter.
826
+ >>> edges = [0, band[0] - trans_width, band[0], band[1],
827
+ ... band[1] + trans_width, 0.5*fs]
828
+ >>> taps = signal.remez(numtaps, edges, [1, 0, 1], fs=fs)
829
+ >>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
830
+ >>> plot_response(w, h, "Band-stop Filter")
831
+ >>> plt.show()
832
+
833
+ """
834
+ xp = array_namespace(bands, desired, weight)
835
+ bands = np.asarray(bands)
836
+ desired = np.asarray(desired)
837
+ if weight is not None:
838
+ weight = np.asarray(weight)
839
+
840
+ fs = _validate_fs(fs, allow_none=True)
841
+ fs = 1.0 if fs is None else fs
842
+
843
+ # Convert type
844
+ try:
845
+ tnum = {'bandpass': 1, 'differentiator': 2, 'hilbert': 3}[type]
846
+ except KeyError as e:
847
+ raise ValueError("Type must be 'bandpass', 'differentiator', "
848
+ "or 'hilbert'") from e
849
+
850
+ # Convert weight
851
+ if weight is None:
852
+ weight = [1] * len(desired)
853
+
854
+ bands = np.asarray(bands).copy()
855
+ result = _sigtools._remez(numtaps, bands, desired, weight, tnum, fs,
856
+ maxiter, grid_density)
857
+ return xp.asarray(result)
858
+
859
+
860
+ def firls(numtaps, bands, desired, *, weight=None, fs=None):
861
+ """
862
+ FIR filter design using least-squares error minimization.
863
+
864
+ Calculate the filter coefficients for the linear-phase finite
865
+ impulse response (FIR) filter which has the best approximation
866
+ to the desired frequency response described by `bands` and
867
+ `desired` in the least squares sense (i.e., the integral of the
868
+ weighted mean-squared error within the specified bands is
869
+ minimized).
870
+
871
+ Parameters
872
+ ----------
873
+ numtaps : int
874
+ The number of taps in the FIR filter. `numtaps` must be odd.
875
+ bands : array_like
876
+ A monotonic nondecreasing sequence containing the band edges in
877
+ Hz. All elements must be non-negative and less than or equal to
878
+ the Nyquist frequency given by `nyq`. The bands are specified as
879
+ frequency pairs, thus, if using a 1D array, its length must be
880
+ even, e.g., `np.array([0, 1, 2, 3, 4, 5])`. Alternatively, the
881
+ bands can be specified as an nx2 sized 2D array, where n is the
882
+ number of bands, e.g, `np.array([[0, 1], [2, 3], [4, 5]])`.
883
+ desired : array_like
884
+ A sequence the same size as `bands` containing the desired gain
885
+ at the start and end point of each band.
886
+ weight : array_like, optional
887
+ A relative weighting to give to each band region when solving
888
+ the least squares problem. `weight` has to be half the size of
889
+ `bands`.
890
+ fs : float, optional
891
+ The sampling frequency of the signal. Each frequency in `bands`
892
+ must be between 0 and ``fs/2`` (inclusive). Default is 2.
893
+
894
+ Returns
895
+ -------
896
+ coeffs : ndarray
897
+ Coefficients of the optimal (in a least squares sense) FIR filter.
898
+
899
+ See Also
900
+ --------
901
+ firwin
902
+ firwin2
903
+ minimum_phase
904
+ remez
905
+
906
+ Notes
907
+ -----
908
+ This implementation follows the algorithm given in [1]_.
909
+ As noted there, least squares design has multiple advantages:
910
+
911
+ 1. Optimal in a least-squares sense.
912
+ 2. Simple, non-iterative method.
913
+ 3. The general solution can obtained by solving a linear
914
+ system of equations.
915
+ 4. Allows the use of a frequency dependent weighting function.
916
+
917
+ This function constructs a Type I linear phase FIR filter, which
918
+ contains an odd number of `coeffs` satisfying for :math:`n < numtaps`:
919
+
920
+ .. math:: coeffs(n) = coeffs(numtaps - 1 - n)
921
+
922
+ The odd number of coefficients and filter symmetry avoid boundary
923
+ conditions that could otherwise occur at the Nyquist and 0 frequencies
924
+ (e.g., for Type II, III, or IV variants).
925
+
926
+ .. versionadded:: 0.18
927
+
928
+ References
929
+ ----------
930
+ .. [1] Ivan Selesnick, Linear-Phase Fir Filter Design By Least Squares.
931
+ OpenStax CNX. Aug 9, 2005.
932
+ https://eeweb.engineering.nyu.edu/iselesni/EL713/firls/firls.pdf
933
+
934
+ Examples
935
+ --------
936
+ We want to construct a band-pass filter. Note that the behavior in the
937
+ frequency ranges between our stop bands and pass bands is unspecified,
938
+ and thus may overshoot depending on the parameters of our filter:
939
+
940
+ >>> import numpy as np
941
+ >>> from scipy import signal
942
+ >>> import matplotlib.pyplot as plt
943
+ >>> fig, axs = plt.subplots(2)
944
+ >>> fs = 10.0 # Hz
945
+ >>> desired = (0, 0, 1, 1, 0, 0)
946
+ >>> for bi, bands in enumerate(((0, 1, 2, 3, 4, 5), (0, 1, 2, 4, 4.5, 5))):
947
+ ... fir_firls = signal.firls(73, bands, desired, fs=fs)
948
+ ... fir_remez = signal.remez(73, bands, desired[::2], fs=fs)
949
+ ... fir_firwin2 = signal.firwin2(73, bands, desired, fs=fs)
950
+ ... hs = list()
951
+ ... ax = axs[bi]
952
+ ... for fir in (fir_firls, fir_remez, fir_firwin2):
953
+ ... freq, response = signal.freqz(fir)
954
+ ... hs.append(ax.semilogy(0.5*fs*freq/np.pi, np.abs(response))[0])
955
+ ... for band, gains in zip(zip(bands[::2], bands[1::2]),
956
+ ... zip(desired[::2], desired[1::2])):
957
+ ... ax.semilogy(band, np.maximum(gains, 1e-7), 'k--', linewidth=2)
958
+ ... if bi == 0:
959
+ ... ax.legend(hs, ('firls', 'remez', 'firwin2'),
960
+ ... loc='lower center', frameon=False)
961
+ ... else:
962
+ ... ax.set_xlabel('Frequency (Hz)')
963
+ ... ax.grid(True)
964
+ ... ax.set(title='Band-pass %d-%d Hz' % bands[2:4], ylabel='Magnitude')
965
+ ...
966
+ >>> fig.tight_layout()
967
+ >>> plt.show()
968
+
969
+ """
970
+ xp = array_namespace(bands, desired)
971
+ bands = np.asarray(bands)
972
+ desired = np.asarray(desired)
973
+
974
+ fs = _validate_fs(fs, allow_none=True)
975
+ fs = 2 if fs is None else fs
976
+ nyq = 0.5 * fs
977
+
978
+ numtaps = int(numtaps)
979
+ if numtaps % 2 == 0 or numtaps < 1:
980
+ raise ValueError("numtaps must be odd and >= 1")
981
+ M = (numtaps-1) // 2
982
+
983
+ # normalize bands 0->1 and make it 2 columns
984
+ nyq = float(nyq)
985
+ if nyq <= 0:
986
+ raise ValueError(f'nyq must be positive, got {nyq} <= 0.')
987
+ bands = np.asarray(bands).flatten() / nyq
988
+ if len(bands) % 2 != 0:
989
+ raise ValueError("bands must contain frequency pairs.")
990
+ if (bands < 0).any() or (bands > 1).any():
991
+ raise ValueError("bands must be between 0 and 1 relative to Nyquist")
992
+ bands.shape = (-1, 2)
993
+
994
+ # check remaining params
995
+ desired = np.asarray(desired).flatten()
996
+ if bands.size != desired.size:
997
+ raise ValueError(
998
+ f"desired must have one entry per frequency, got {desired.size} "
999
+ f"gains for {bands.size} frequencies."
1000
+ )
1001
+ desired.shape = (-1, 2)
1002
+ if (np.diff(bands) <= 0).any() or (np.diff(bands[:, 0]) < 0).any():
1003
+ raise ValueError("bands must be monotonically nondecreasing and have "
1004
+ "width > 0.")
1005
+ if (bands[:-1, 1] > bands[1:, 0]).any():
1006
+ raise ValueError("bands must not overlap.")
1007
+ if (desired < 0).any():
1008
+ raise ValueError("desired must be non-negative.")
1009
+ if weight is None:
1010
+ weight = np.ones(len(desired))
1011
+ weight = np.asarray(weight).flatten()
1012
+ if len(weight) != len(desired):
1013
+ raise ValueError("weight must be the same size as the number of "
1014
+ f"band pairs ({len(bands)}).")
1015
+ if (weight < 0).any():
1016
+ raise ValueError("weight must be non-negative.")
1017
+
1018
+ # Set up the linear matrix equation to be solved, Qa = b
1019
+
1020
+ # We can express Q(k,n) = 0.5 Q1(k,n) + 0.5 Q2(k,n)
1021
+ # where Q1(k,n)=q(k-n) and Q2(k,n)=q(k+n), i.e. a Toeplitz plus Hankel.
1022
+
1023
+ # We omit the factor of 0.5 above, instead adding it during coefficient
1024
+ # calculation.
1025
+
1026
+ # We also omit the 1/π from both Q and b equations, as they cancel
1027
+ # during solving.
1028
+
1029
+ # We have that:
1030
+ # q(n) = 1/π ∫W(ω)cos(nω)dω (over 0->π)
1031
+ # Using our normalization ω=πf and with a constant weight W over each
1032
+ # interval f1->f2 we get:
1033
+ # q(n) = W∫cos(πnf)df (0->1) = Wf sin(πnf)/πnf
1034
+ # integrated over each f1->f2 pair (i.e., value at f2 - value at f1).
1035
+ n = np.arange(numtaps)[:, np.newaxis, np.newaxis]
1036
+ q = np.dot(np.diff(np.sinc(bands * n) * bands, axis=2)[:, :, 0], weight)
1037
+
1038
+ # Now we assemble our sum of Toeplitz and Hankel
1039
+ Q1 = toeplitz(q[:M+1])
1040
+ Q2 = hankel(q[:M+1], q[M:])
1041
+ Q = Q1 + Q2
1042
+
1043
+ # Now for b(n) we have that:
1044
+ # b(n) = 1/π ∫ W(ω)D(ω)cos(nω)dω (over 0->π)
1045
+ # Using our normalization ω=πf and with a constant weight W over each
1046
+ # interval and a linear term for D(ω) we get (over each f1->f2 interval):
1047
+ # b(n) = W ∫ (mf+c)cos(πnf)df
1048
+ # = f(mf+c)sin(πnf)/πnf + mf**2 cos(nπf)/(πnf)**2
1049
+ # integrated over each f1->f2 pair (i.e., value at f2 - value at f1).
1050
+ n = n[:M + 1] # only need this many coefficients here
1051
+ # Choose m and c such that we are at the start and end weights
1052
+ m = (np.diff(desired, axis=1) / np.diff(bands, axis=1))
1053
+ c = desired[:, [0]] - bands[:, [0]] * m
1054
+ b = bands * (m*bands + c) * np.sinc(bands * n)
1055
+ # Use L'Hospital's rule here for cos(nπf)/(πnf)**2 @ n=0
1056
+ b[0] -= m * bands * bands / 2.
1057
+ b[1:] += m * np.cos(n[1:] * np.pi * bands) / (np.pi * n[1:]) ** 2
1058
+ b = np.dot(np.diff(b, axis=2)[:, :, 0], weight)
1059
+
1060
+ # Now we can solve the equation
1061
+ try: # try the fast way
1062
+ with warnings.catch_warnings(record=True) as w:
1063
+ warnings.simplefilter('always')
1064
+ a = solve(Q, b, assume_a="pos", check_finite=False)
1065
+ for ww in w:
1066
+ if (ww.category == LinAlgWarning and
1067
+ str(ww.message).startswith('Ill-conditioned matrix')):
1068
+ raise LinAlgError(str(ww.message))
1069
+ except LinAlgError: # in case Q is rank deficient
1070
+ # This is faster than pinvh, even though we don't explicitly use
1071
+ # the symmetry here. gelsy was faster than gelsd and gelss in
1072
+ # some non-exhaustive tests.
1073
+ a = lstsq(Q, b, lapack_driver='gelsy')[0]
1074
+
1075
+ # make coefficients symmetric (linear phase)
1076
+ coeffs = np.hstack((a[:0:-1], 2 * a[0], a[1:]))
1077
+ return xp.asarray(coeffs)
1078
+
1079
+
1080
+ def _dhtm(mag, xp):
1081
+ """Compute the modified 1-D discrete Hilbert transform
1082
+
1083
+ Parameters
1084
+ ----------
1085
+ mag : ndarray
1086
+ The magnitude spectrum. Should be 1-D with an even length, and
1087
+ preferably a fast length for FFT/IFFT.
1088
+ """
1089
+ # Adapted based on code by Niranjan Damera-Venkata,
1090
+ # Brian L. Evans and Shawn R. McCaslin (see refs for `minimum_phase`)
1091
+ sig = xp.zeros(mag.shape[0])
1092
+ # Leave Nyquist and DC at 0, knowing np.abs(fftfreq(N)[midpt]) == 0.5
1093
+ midpt = mag.shape[0] // 2
1094
+ sig[1:midpt] = 1
1095
+ sig[midpt+1:] = -1
1096
+ # eventually if we want to support complex filters, we will need a
1097
+ # np.abs() on the mag inside the log, and should remove the .real
1098
+ recon = xp.real(ifft(mag * xp.exp(fft(sig * ifft(xp.log(mag))))))
1099
+ return recon
1100
+
1101
+
1102
+ def minimum_phase(h,
1103
+ method: Literal['homomorphic', 'hilbert'] = 'homomorphic',
1104
+ n_fft: int | None = None, *, half: bool = True):
1105
+ """Convert a linear-phase FIR filter to minimum phase
1106
+
1107
+ Parameters
1108
+ ----------
1109
+ h : array
1110
+ Linear-phase FIR filter coefficients.
1111
+ method : {'hilbert', 'homomorphic'}
1112
+ The provided methods are:
1113
+
1114
+ 'homomorphic' (default)
1115
+ This method [4]_ [5]_ works best with filters with an
1116
+ odd number of taps, and the resulting minimum phase filter
1117
+ will have a magnitude response that approximates the square
1118
+ root of the original filter's magnitude response using half
1119
+ the number of taps when ``half=True`` (default), or the
1120
+ original magnitude spectrum using the same number of taps
1121
+ when ``half=False``.
1122
+
1123
+ 'hilbert'
1124
+ This method [1]_ is designed to be used with equiripple
1125
+ filters (e.g., from `remez`) with unity or zero gain
1126
+ regions.
1127
+
1128
+ n_fft : int
1129
+ The number of points to use for the FFT. Should be at least a
1130
+ few times larger than the signal length (see Notes).
1131
+ half : bool
1132
+ If ``True``, create a filter that is half the length of the original, with a
1133
+ magnitude spectrum that is the square root of the original. If ``False``,
1134
+ create a filter that is the same length as the original, with a magnitude
1135
+ spectrum that is designed to match the original (only supported when
1136
+ ``method='homomorphic'``).
1137
+
1138
+ .. versionadded:: 1.14.0
1139
+
1140
+ Returns
1141
+ -------
1142
+ h_minimum : array
1143
+ The minimum-phase version of the filter, with length
1144
+ ``(len(h) + 1) // 2`` when ``half is True`` or ``len(h)`` otherwise.
1145
+
1146
+ See Also
1147
+ --------
1148
+ firwin
1149
+ firwin2
1150
+ remez
1151
+
1152
+ Notes
1153
+ -----
1154
+ Both the Hilbert [1]_ or homomorphic [4]_ [5]_ methods require selection
1155
+ of an FFT length to estimate the complex cepstrum of the filter.
1156
+
1157
+ In the case of the Hilbert method, the deviation from the ideal
1158
+ spectrum ``epsilon`` is related to the number of stopband zeros
1159
+ ``n_stop`` and FFT length ``n_fft`` as::
1160
+
1161
+ epsilon = 2. * n_stop / n_fft
1162
+
1163
+ For example, with 100 stopband zeros and a FFT length of 2048,
1164
+ ``epsilon = 0.0976``. If we conservatively assume that the number of
1165
+ stopband zeros is one less than the filter length, we can take the FFT
1166
+ length to be the next power of 2 that satisfies ``epsilon=0.01`` as::
1167
+
1168
+ n_fft = 2 ** int(np.ceil(np.log2(2 * (len(h) - 1) / 0.01)))
1169
+
1170
+ This gives reasonable results for both the Hilbert and homomorphic
1171
+ methods, and gives the value used when ``n_fft=None``.
1172
+
1173
+ Alternative implementations exist for creating minimum-phase filters,
1174
+ including zero inversion [2]_ and spectral factorization [3]_ [4]_.
1175
+ For more information, see `this DSPGuru page
1176
+ <http://dspguru.com/dsp/howtos/how-to-design-minimum-phase-fir-filters>`__.
1177
+
1178
+ References
1179
+ ----------
1180
+ .. [1] N. Damera-Venkata and B. L. Evans, "Optimal design of real and
1181
+ complex minimum phase digital FIR filters," Acoustics, Speech,
1182
+ and Signal Processing, 1999. Proceedings., 1999 IEEE International
1183
+ Conference on, Phoenix, AZ, 1999, pp. 1145-1148 vol.3.
1184
+ :doi:`10.1109/ICASSP.1999.756179`
1185
+ .. [2] X. Chen and T. W. Parks, "Design of optimal minimum phase FIR
1186
+ filters by direct factorization," Signal Processing,
1187
+ vol. 10, no. 4, pp. 369-383, Jun. 1986.
1188
+ .. [3] T. Saramaki, "Finite Impulse Response Filter Design," in
1189
+ Handbook for Digital Signal Processing, chapter 4,
1190
+ New York: Wiley-Interscience, 1993.
1191
+ .. [4] J. S. Lim, Advanced Topics in Signal Processing.
1192
+ Englewood Cliffs, N.J.: Prentice Hall, 1988.
1193
+ .. [5] A. V. Oppenheim, R. W. Schafer, and J. R. Buck,
1194
+ "Discrete-Time Signal Processing," 3rd edition.
1195
+ Upper Saddle River, N.J.: Pearson, 2009.
1196
+
1197
+ Examples
1198
+ --------
1199
+ Create an optimal linear-phase low-pass filter `h` with a transition band of
1200
+ [0.2, 0.3] (assuming a Nyquist frequency of 1):
1201
+
1202
+ >>> import numpy as np
1203
+ >>> from scipy.signal import remez, minimum_phase, freqz, group_delay
1204
+ >>> import matplotlib.pyplot as plt
1205
+ >>> freq = [0, 0.2, 0.3, 1.0]
1206
+ >>> desired = [1, 0]
1207
+ >>> h_linear = remez(151, freq, desired, fs=2)
1208
+
1209
+ Convert it to minimum phase:
1210
+
1211
+ >>> h_hil = minimum_phase(h_linear, method='hilbert')
1212
+ >>> h_hom = minimum_phase(h_linear, method='homomorphic')
1213
+ >>> h_hom_full = minimum_phase(h_linear, method='homomorphic', half=False)
1214
+
1215
+ Compare the impulse and frequency response of the four filters:
1216
+
1217
+ >>> fig0, ax0 = plt.subplots(figsize=(6, 3), tight_layout=True)
1218
+ >>> fig1, axs = plt.subplots(3, sharex='all', figsize=(6, 6), tight_layout=True)
1219
+ >>> ax0.set_title("Impulse response")
1220
+ >>> ax0.set(xlabel='Samples', ylabel='Amplitude', xlim=(0, len(h_linear) - 1))
1221
+ >>> axs[0].set_title("Frequency Response")
1222
+ >>> axs[0].set(xlim=(0, .65), ylabel="Magnitude / dB")
1223
+ >>> axs[1].set(ylabel="Phase / rad")
1224
+ >>> axs[2].set(ylabel="Group Delay / samples", ylim=(-31, 81),
1225
+ ... xlabel='Normalized Frequency (Nyqist frequency: 1)')
1226
+ >>> for h, lb in ((h_linear, f'Linear ({len(h_linear)})'),
1227
+ ... (h_hil, f'Min-Hilbert ({len(h_hil)})'),
1228
+ ... (h_hom, f'Min-Homomorphic ({len(h_hom)})'),
1229
+ ... (h_hom_full, f'Min-Homom. Full ({len(h_hom_full)})')):
1230
+ ... w_H, H = freqz(h, fs=2)
1231
+ ... w_gd, gd = group_delay((h, 1), fs=2)
1232
+ ...
1233
+ ... alpha = 1.0 if lb == 'linear' else 0.5 # full opacity for 'linear' line
1234
+ ... ax0.plot(h, '.-', alpha=alpha, label=lb)
1235
+ ... axs[0].plot(w_H, 20 * np.log10(np.abs(H)), alpha=alpha)
1236
+ ... axs[1].plot(w_H, np.unwrap(np.angle(H)), alpha=alpha, label=lb)
1237
+ ... axs[2].plot(w_gd, gd, alpha=alpha)
1238
+ >>> ax0.grid(True)
1239
+ >>> ax0.legend(title='Filter Phase (Order)')
1240
+ >>> axs[1].legend(title='Filter Phase (Order)', loc='lower right')
1241
+ >>> for ax_ in axs: # shade transition band:
1242
+ ... ax_.axvspan(freq[1], freq[2], color='y', alpha=.25)
1243
+ ... ax_.grid(True)
1244
+ >>> plt.show()
1245
+
1246
+ The impulse response and group delay plot depict the 75 sample delay of the linear
1247
+ phase filter `h`. The phase should also be linear in the stop band--due to the small
1248
+ magnitude, numeric noise dominates there. Furthermore, the plots show that the
1249
+ minimum phase filters clearly show a reduced (negative) phase slope in the pass and
1250
+ transition band. The plots also illustrate that the filter with parameters
1251
+ ``method='homomorphic', half=False`` has same order and magnitude response as the
1252
+ linear filter `h` whereas the other minimum phase filters have only half the order
1253
+ and the square root of the magnitude response.
1254
+ """
1255
+ xp = array_namespace(h)
1256
+
1257
+ h = xp.asarray(h)
1258
+ if xp.isdtype(h.dtype, "complex floating"):
1259
+ raise ValueError('Complex filters not supported')
1260
+ if h.ndim != 1 or h.shape[0] <= 2:
1261
+ raise ValueError('h must be 1-D and at least 2 samples long')
1262
+ n_half = h.shape[0] // 2
1263
+
1264
+ if not xp.any(xp.flip(h[-n_half:]) - h[:n_half] <= 1e-8 + 1e-6*abs(h[:n_half])):
1265
+ warnings.warn('h does not appear to by symmetric, conversion may fail',
1266
+ RuntimeWarning, stacklevel=2)
1267
+ if not isinstance(method, str) or method not in \
1268
+ ('homomorphic', 'hilbert',):
1269
+ raise ValueError(f'method must be "homomorphic" or "hilbert", got {method!r}')
1270
+ if method == "hilbert" and not half:
1271
+ raise ValueError("`half=False` is only supported when `method='homomorphic'`")
1272
+ if n_fft is None:
1273
+ n_fft = 2 ** int(ceil(log2(2 * (h.shape[0] - 1) / 0.01)))
1274
+ n_fft = int(n_fft)
1275
+ if n_fft < h.shape[0]:
1276
+ raise ValueError(f'n_fft must be at least len(h)=={len(h)}')
1277
+
1278
+ if method == 'hilbert':
1279
+ w = xp.arange(n_fft, dtype=xp.float64) * (2 * xp.pi / n_fft * n_half)
1280
+ H = xp.real(fft(h, n_fft) * xp.exp(1j * w))
1281
+ dp = max(H) - 1
1282
+ ds = 0 - min(H)
1283
+ S = 4. / (xp.sqrt(1+dp+ds) + xp.sqrt(1-dp+ds)) ** 2
1284
+ H += ds
1285
+ H *= S
1286
+ H = xp.sqrt(H)
1287
+ H += 1e-10 # ensure that the log does not explode
1288
+ h_minimum = _dhtm(H, xp)
1289
+ else: # method == 'homomorphic'
1290
+ # zero-pad; calculate the DFT
1291
+ h_temp = xp.abs(fft(h, n_fft))
1292
+ # take 0.25*log(|H|**2) = 0.5*log(|H|)
1293
+ h_temp += 1e-7 * xp.min(h_temp[h_temp > 0]) # don't let log blow up
1294
+ h_temp = xp.log(h_temp)
1295
+ if half: # halving of magnitude spectrum optional
1296
+ h_temp *= 0.5
1297
+ # IDFT
1298
+ h_temp = xp.real(ifft(h_temp))
1299
+ # multiply pointwise by the homomorphic filter
1300
+ # lmin[n] = 2u[n] - d[n]
1301
+ # i.e., double the positive frequencies and zero out the negative ones;
1302
+ # Oppenheim+Shafer 3rd ed p991 eq13.42b and p1004 fig13.7
1303
+ win = xp.zeros(n_fft)
1304
+ win[0] = 1
1305
+ stop = n_fft // 2
1306
+ win[1:stop] = 2
1307
+ if n_fft % 2:
1308
+ win[stop] = 1
1309
+ h_temp *= win
1310
+ h_temp = ifft(xp.exp(fft(h_temp)))
1311
+ h_minimum = h_temp.real
1312
+ n_out = (n_half + h.shape[0] % 2) if half else h.shape[0]
1313
+ return h_minimum[:n_out]
1314
+
1315
+
1316
+ def firwin_2d(hsize, window, *, fc=None, fs=2, circular=False,
1317
+ pass_zero=True, scale=True):
1318
+ """
1319
+ 2D FIR filter design using the window method.
1320
+
1321
+ This function computes the coefficients of a 2D finite impulse response
1322
+ filter. The filter is separable with linear phase; it will be designed
1323
+ as a product of two 1D filters with dimensions defined by `hsize`.
1324
+ Additionally, it can create approximately circularly symmetric 2-D windows.
1325
+
1326
+ Parameters
1327
+ ----------
1328
+ hsize : tuple or list of length 2
1329
+ Lengths of the filter in each dimension. `hsize[0]` specifies the
1330
+ number of coefficients in the row direction and `hsize[1]` specifies
1331
+ the number of coefficients in the column direction.
1332
+ window : tuple or list of length 2 or string
1333
+ Desired window to use for each 1D filter or a single window type
1334
+ for creating circularly symmetric 2-D windows. Each element should be
1335
+ a string or tuple of string and parameter values. See
1336
+ `~scipy.signal.get_window` for a list of windows and required
1337
+ parameters.
1338
+ fc : float or 1-D array_like, optional
1339
+ Cutoff frequency of the filter in the same units as `fs`. This defines
1340
+ the frequency at which the filter's gain drops to approximately -6 dB
1341
+ (half power) in a low-pass or high-pass filter. For multi-band filters,
1342
+ `fc` can be an array of cutoff frequencies (i.e., band edges) in the
1343
+ range [0, fs/2], with each band specified in pairs. Required if
1344
+ `circular` is False.
1345
+ fs : float, optional
1346
+ The sampling frequency of the signal. Default is 2.
1347
+ circular : bool, optional
1348
+ Whether to create a circularly symmetric 2-D window. Default is ``False``.
1349
+ pass_zero : {True, False, 'bandpass', 'lowpass', 'highpass', 'bandstop'}, optional
1350
+ This parameter is directly passed to `firwin` for each scalar frequency axis.
1351
+ Hence, if ``True``, the DC gain, i.e., the gain at frequency (0, 0), is 1.
1352
+ If ``False``, the DC gain is 0 at frequency (0, 0) if `circular` is ``True``.
1353
+ If `circular` is ``False`` the frequencies (0, f1) and (f0, 0) will
1354
+ have gain 0.
1355
+ It can also be a string argument for the desired filter type
1356
+ (equivalent to ``btype`` in IIR design functions).
1357
+ scale : bool, optional
1358
+ This parameter is directly passed to `firwin` for each scalar frequency axis.
1359
+ Set to ``True`` to scale the coefficients so that the frequency
1360
+ response is exactly unity at a certain frequency on one frequency axis.
1361
+ That frequency is either:
1362
+
1363
+ - 0 (DC) if the first passband starts at 0 (i.e. pass_zero is ``True``)
1364
+ - `fs`/2 (the Nyquist frequency) if the first passband ends at `fs`/2
1365
+ (i.e., the filter is a single band highpass filter);
1366
+ center of first passband otherwise
1367
+
1368
+ Returns
1369
+ -------
1370
+ filter_2d : (hsize[0], hsize[1]) ndarray
1371
+ Coefficients of 2D FIR filter.
1372
+
1373
+ Raises
1374
+ ------
1375
+ ValueError
1376
+ - If `hsize` and `window` are not 2-element tuples or lists.
1377
+ - If `cutoff` is None when `circular` is True.
1378
+ - If `cutoff` is outside the range [0, `fs`/2] and `circular` is ``False``.
1379
+ - If any of the elements in `window` are not recognized.
1380
+ RuntimeError
1381
+ If `firwin` fails to converge when designing the filter.
1382
+
1383
+ See Also
1384
+ --------
1385
+ firwin: FIR filter design using the window method for 1d arrays.
1386
+ get_window: Return a window of a given length and type.
1387
+
1388
+ Examples
1389
+ --------
1390
+ Generate a 5x5 low-pass filter with cutoff frequency 0.1:
1391
+
1392
+ >>> import numpy as np
1393
+ >>> from scipy.signal import get_window
1394
+ >>> from scipy.signal import firwin_2d
1395
+ >>> hsize = (5, 5)
1396
+ >>> window = (("kaiser", 5.0), ("kaiser", 5.0))
1397
+ >>> fc = 0.1
1398
+ >>> filter_2d = firwin_2d(hsize, window, fc=fc)
1399
+ >>> filter_2d
1400
+ array([[0.00025366, 0.00401662, 0.00738617, 0.00401662, 0.00025366],
1401
+ [0.00401662, 0.06360159, 0.11695714, 0.06360159, 0.00401662],
1402
+ [0.00738617, 0.11695714, 0.21507283, 0.11695714, 0.00738617],
1403
+ [0.00401662, 0.06360159, 0.11695714, 0.06360159, 0.00401662],
1404
+ [0.00025366, 0.00401662, 0.00738617, 0.00401662, 0.00025366]])
1405
+
1406
+ Generate a circularly symmetric 5x5 low-pass filter with Hamming window:
1407
+
1408
+ >>> filter_2d = firwin_2d((5, 5), 'hamming', fc=fc, circular=True)
1409
+ >>> filter_2d
1410
+ array([[-0.00020354, -0.00020354, -0.00020354, -0.00020354, -0.00020354],
1411
+ [-0.00020354, 0.01506844, 0.09907658, 0.01506844, -0.00020354],
1412
+ [-0.00020354, 0.09907658, -0.00020354, 0.09907658, -0.00020354],
1413
+ [-0.00020354, 0.01506844, 0.09907658, 0.01506844, -0.00020354],
1414
+ [-0.00020354, -0.00020354, -0.00020354, -0.00020354, -0.00020354]])
1415
+
1416
+ Generate Plots comparing the product of two 1d filters with a circular
1417
+ symmetric filter:
1418
+
1419
+ >>> import matplotlib.pyplot as plt
1420
+ >>> hsize, fc = (50, 50), 0.05
1421
+ >>> window = (("kaiser", 5.0), ("kaiser", 5.0))
1422
+ >>> filter0_2d = firwin_2d(hsize, window, fc=fc)
1423
+ >>> filter1_2d = firwin_2d((50, 50), 'hamming', fc=fc, circular=True)
1424
+ ...
1425
+ >>> fg, (ax0, ax1) = plt.subplots(1, 2, tight_layout=True, figsize=(6.5, 3.5))
1426
+ >>> ax0.set_title("Product of 2 Windows")
1427
+ >>> im0 = ax0.imshow(filter0_2d, cmap='viridis', origin='lower', aspect='equal')
1428
+ >>> fg.colorbar(im0, ax=ax0, shrink=0.7)
1429
+ >>> ax1.set_title("Circular Window")
1430
+ >>> im1 = ax1.imshow(filter1_2d, cmap='plasma', origin='lower', aspect='equal')
1431
+ >>> fg.colorbar(im1, ax=ax1, shrink=0.7)
1432
+ >>> plt.show()
1433
+ """
1434
+ if len(hsize) != 2:
1435
+ raise ValueError("hsize must be a 2-element tuple or list")
1436
+
1437
+ if circular:
1438
+ if fc is None:
1439
+ raise ValueError("Cutoff frequency `fc` must be "
1440
+ "provided when `circular` is True")
1441
+
1442
+ n_r = max(hsize[0], hsize[1]) * 8 # oversample 1d window by factor 8
1443
+
1444
+ win_r = firwin(n_r, cutoff=fc, window=window, fs=fs)
1445
+
1446
+ f1, f2 = np.meshgrid(np.linspace(-1, 1, hsize[0]), np.linspace(-1, 1, hsize[1]))
1447
+ r = np.sqrt(f1**2 + f2**2)
1448
+
1449
+ win_2d = np.interp(r, np.linspace(0, 1, n_r), win_r)
1450
+ return win_2d
1451
+
1452
+ if len(window) != 2:
1453
+ raise ValueError("window must be a 2-element tuple or list")
1454
+
1455
+ row_filter = firwin(hsize[0], cutoff=fc, window=window[0], fs=fs)
1456
+ col_filter = firwin(hsize[1], cutoff=fc, window=window[1], fs=fs)
1457
+
1458
+ return np.outer(row_filter, col_filter)