scipy 1.16.2__cp311-cp311-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1530) hide show
  1. scipy/__config__.py +161 -0
  2. scipy/__init__.py +150 -0
  3. scipy/_cyutility.cp311-win_arm64.lib +0 -0
  4. scipy/_cyutility.cp311-win_arm64.pyd +0 -0
  5. scipy/_distributor_init.py +18 -0
  6. scipy/_lib/__init__.py +14 -0
  7. scipy/_lib/_array_api.py +931 -0
  8. scipy/_lib/_array_api_compat_vendor.py +9 -0
  9. scipy/_lib/_array_api_no_0d.py +103 -0
  10. scipy/_lib/_bunch.py +229 -0
  11. scipy/_lib/_ccallback.py +251 -0
  12. scipy/_lib/_ccallback_c.cp311-win_arm64.lib +0 -0
  13. scipy/_lib/_ccallback_c.cp311-win_arm64.pyd +0 -0
  14. scipy/_lib/_disjoint_set.py +254 -0
  15. scipy/_lib/_docscrape.py +761 -0
  16. scipy/_lib/_elementwise_iterative_method.py +346 -0
  17. scipy/_lib/_fpumode.cp311-win_arm64.lib +0 -0
  18. scipy/_lib/_fpumode.cp311-win_arm64.pyd +0 -0
  19. scipy/_lib/_gcutils.py +105 -0
  20. scipy/_lib/_pep440.py +487 -0
  21. scipy/_lib/_sparse.py +41 -0
  22. scipy/_lib/_test_ccallback.cp311-win_arm64.lib +0 -0
  23. scipy/_lib/_test_ccallback.cp311-win_arm64.pyd +0 -0
  24. scipy/_lib/_test_deprecation_call.cp311-win_arm64.lib +0 -0
  25. scipy/_lib/_test_deprecation_call.cp311-win_arm64.pyd +0 -0
  26. scipy/_lib/_test_deprecation_def.cp311-win_arm64.lib +0 -0
  27. scipy/_lib/_test_deprecation_def.cp311-win_arm64.pyd +0 -0
  28. scipy/_lib/_testutils.py +373 -0
  29. scipy/_lib/_threadsafety.py +58 -0
  30. scipy/_lib/_tmpdirs.py +86 -0
  31. scipy/_lib/_uarray/LICENSE +29 -0
  32. scipy/_lib/_uarray/__init__.py +116 -0
  33. scipy/_lib/_uarray/_backend.py +707 -0
  34. scipy/_lib/_uarray/_uarray.cp311-win_arm64.lib +0 -0
  35. scipy/_lib/_uarray/_uarray.cp311-win_arm64.pyd +0 -0
  36. scipy/_lib/_util.py +1283 -0
  37. scipy/_lib/array_api_compat/__init__.py +22 -0
  38. scipy/_lib/array_api_compat/_internal.py +59 -0
  39. scipy/_lib/array_api_compat/common/__init__.py +1 -0
  40. scipy/_lib/array_api_compat/common/_aliases.py +727 -0
  41. scipy/_lib/array_api_compat/common/_fft.py +213 -0
  42. scipy/_lib/array_api_compat/common/_helpers.py +1058 -0
  43. scipy/_lib/array_api_compat/common/_linalg.py +232 -0
  44. scipy/_lib/array_api_compat/common/_typing.py +192 -0
  45. scipy/_lib/array_api_compat/cupy/__init__.py +13 -0
  46. scipy/_lib/array_api_compat/cupy/_aliases.py +156 -0
  47. scipy/_lib/array_api_compat/cupy/_info.py +336 -0
  48. scipy/_lib/array_api_compat/cupy/_typing.py +31 -0
  49. scipy/_lib/array_api_compat/cupy/fft.py +36 -0
  50. scipy/_lib/array_api_compat/cupy/linalg.py +49 -0
  51. scipy/_lib/array_api_compat/dask/__init__.py +0 -0
  52. scipy/_lib/array_api_compat/dask/array/__init__.py +12 -0
  53. scipy/_lib/array_api_compat/dask/array/_aliases.py +376 -0
  54. scipy/_lib/array_api_compat/dask/array/_info.py +416 -0
  55. scipy/_lib/array_api_compat/dask/array/fft.py +21 -0
  56. scipy/_lib/array_api_compat/dask/array/linalg.py +72 -0
  57. scipy/_lib/array_api_compat/numpy/__init__.py +28 -0
  58. scipy/_lib/array_api_compat/numpy/_aliases.py +190 -0
  59. scipy/_lib/array_api_compat/numpy/_info.py +366 -0
  60. scipy/_lib/array_api_compat/numpy/_typing.py +30 -0
  61. scipy/_lib/array_api_compat/numpy/fft.py +35 -0
  62. scipy/_lib/array_api_compat/numpy/linalg.py +143 -0
  63. scipy/_lib/array_api_compat/torch/__init__.py +22 -0
  64. scipy/_lib/array_api_compat/torch/_aliases.py +855 -0
  65. scipy/_lib/array_api_compat/torch/_info.py +369 -0
  66. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  67. scipy/_lib/array_api_compat/torch/fft.py +85 -0
  68. scipy/_lib/array_api_compat/torch/linalg.py +121 -0
  69. scipy/_lib/array_api_extra/__init__.py +38 -0
  70. scipy/_lib/array_api_extra/_delegation.py +171 -0
  71. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  72. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  73. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  74. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  75. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  76. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  77. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  78. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  79. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  80. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  81. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  82. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  83. scipy/_lib/array_api_extra/testing.py +359 -0
  84. scipy/_lib/cobyqa/__init__.py +20 -0
  85. scipy/_lib/cobyqa/framework.py +1240 -0
  86. scipy/_lib/cobyqa/main.py +1506 -0
  87. scipy/_lib/cobyqa/models.py +1529 -0
  88. scipy/_lib/cobyqa/problem.py +1296 -0
  89. scipy/_lib/cobyqa/settings.py +132 -0
  90. scipy/_lib/cobyqa/subsolvers/__init__.py +14 -0
  91. scipy/_lib/cobyqa/subsolvers/geometry.py +387 -0
  92. scipy/_lib/cobyqa/subsolvers/optim.py +1203 -0
  93. scipy/_lib/cobyqa/utils/__init__.py +18 -0
  94. scipy/_lib/cobyqa/utils/exceptions.py +22 -0
  95. scipy/_lib/cobyqa/utils/math.py +77 -0
  96. scipy/_lib/cobyqa/utils/versions.py +67 -0
  97. scipy/_lib/decorator.py +399 -0
  98. scipy/_lib/deprecation.py +274 -0
  99. scipy/_lib/doccer.py +366 -0
  100. scipy/_lib/messagestream.cp311-win_arm64.lib +0 -0
  101. scipy/_lib/messagestream.cp311-win_arm64.pyd +0 -0
  102. scipy/_lib/pyprima/__init__.py +212 -0
  103. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  104. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  105. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  106. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  107. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  108. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  109. scipy/_lib/pyprima/cobyla/update.py +289 -0
  110. scipy/_lib/pyprima/common/__init__.py +0 -0
  111. scipy/_lib/pyprima/common/_bounds.py +34 -0
  112. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  113. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  114. scipy/_lib/pyprima/common/_project.py +173 -0
  115. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  116. scipy/_lib/pyprima/common/consts.py +47 -0
  117. scipy/_lib/pyprima/common/evaluate.py +99 -0
  118. scipy/_lib/pyprima/common/history.py +38 -0
  119. scipy/_lib/pyprima/common/infos.py +30 -0
  120. scipy/_lib/pyprima/common/linalg.py +435 -0
  121. scipy/_lib/pyprima/common/message.py +290 -0
  122. scipy/_lib/pyprima/common/powalg.py +131 -0
  123. scipy/_lib/pyprima/common/preproc.py +277 -0
  124. scipy/_lib/pyprima/common/present.py +5 -0
  125. scipy/_lib/pyprima/common/ratio.py +54 -0
  126. scipy/_lib/pyprima/common/redrho.py +47 -0
  127. scipy/_lib/pyprima/common/selectx.py +296 -0
  128. scipy/_lib/tests/__init__.py +0 -0
  129. scipy/_lib/tests/test__gcutils.py +110 -0
  130. scipy/_lib/tests/test__pep440.py +67 -0
  131. scipy/_lib/tests/test__testutils.py +32 -0
  132. scipy/_lib/tests/test__threadsafety.py +51 -0
  133. scipy/_lib/tests/test__util.py +641 -0
  134. scipy/_lib/tests/test_array_api.py +322 -0
  135. scipy/_lib/tests/test_bunch.py +169 -0
  136. scipy/_lib/tests/test_ccallback.py +196 -0
  137. scipy/_lib/tests/test_config.py +45 -0
  138. scipy/_lib/tests/test_deprecation.py +10 -0
  139. scipy/_lib/tests/test_doccer.py +143 -0
  140. scipy/_lib/tests/test_import_cycles.py +18 -0
  141. scipy/_lib/tests/test_public_api.py +482 -0
  142. scipy/_lib/tests/test_scipy_version.py +28 -0
  143. scipy/_lib/tests/test_tmpdirs.py +48 -0
  144. scipy/_lib/tests/test_warnings.py +137 -0
  145. scipy/_lib/uarray.py +31 -0
  146. scipy/cluster/__init__.py +31 -0
  147. scipy/cluster/_hierarchy.cp311-win_arm64.lib +0 -0
  148. scipy/cluster/_hierarchy.cp311-win_arm64.pyd +0 -0
  149. scipy/cluster/_optimal_leaf_ordering.cp311-win_arm64.lib +0 -0
  150. scipy/cluster/_optimal_leaf_ordering.cp311-win_arm64.pyd +0 -0
  151. scipy/cluster/_vq.cp311-win_arm64.lib +0 -0
  152. scipy/cluster/_vq.cp311-win_arm64.pyd +0 -0
  153. scipy/cluster/hierarchy.py +4348 -0
  154. scipy/cluster/tests/__init__.py +0 -0
  155. scipy/cluster/tests/hierarchy_test_data.py +145 -0
  156. scipy/cluster/tests/test_disjoint_set.py +202 -0
  157. scipy/cluster/tests/test_hierarchy.py +1238 -0
  158. scipy/cluster/tests/test_vq.py +434 -0
  159. scipy/cluster/vq.py +832 -0
  160. scipy/conftest.py +683 -0
  161. scipy/constants/__init__.py +358 -0
  162. scipy/constants/_codata.py +2266 -0
  163. scipy/constants/_constants.py +369 -0
  164. scipy/constants/codata.py +21 -0
  165. scipy/constants/constants.py +53 -0
  166. scipy/constants/tests/__init__.py +0 -0
  167. scipy/constants/tests/test_codata.py +78 -0
  168. scipy/constants/tests/test_constants.py +83 -0
  169. scipy/datasets/__init__.py +90 -0
  170. scipy/datasets/_download_all.py +71 -0
  171. scipy/datasets/_fetchers.py +225 -0
  172. scipy/datasets/_registry.py +26 -0
  173. scipy/datasets/_utils.py +81 -0
  174. scipy/datasets/tests/__init__.py +0 -0
  175. scipy/datasets/tests/test_data.py +128 -0
  176. scipy/differentiate/__init__.py +27 -0
  177. scipy/differentiate/_differentiate.py +1129 -0
  178. scipy/differentiate/tests/__init__.py +0 -0
  179. scipy/differentiate/tests/test_differentiate.py +694 -0
  180. scipy/fft/__init__.py +114 -0
  181. scipy/fft/_backend.py +196 -0
  182. scipy/fft/_basic.py +1650 -0
  183. scipy/fft/_basic_backend.py +197 -0
  184. scipy/fft/_debug_backends.py +22 -0
  185. scipy/fft/_fftlog.py +223 -0
  186. scipy/fft/_fftlog_backend.py +200 -0
  187. scipy/fft/_helper.py +348 -0
  188. scipy/fft/_pocketfft/LICENSE.md +25 -0
  189. scipy/fft/_pocketfft/__init__.py +9 -0
  190. scipy/fft/_pocketfft/basic.py +251 -0
  191. scipy/fft/_pocketfft/helper.py +249 -0
  192. scipy/fft/_pocketfft/pypocketfft.cp311-win_arm64.lib +0 -0
  193. scipy/fft/_pocketfft/pypocketfft.cp311-win_arm64.pyd +0 -0
  194. scipy/fft/_pocketfft/realtransforms.py +109 -0
  195. scipy/fft/_pocketfft/tests/__init__.py +0 -0
  196. scipy/fft/_pocketfft/tests/test_basic.py +1011 -0
  197. scipy/fft/_pocketfft/tests/test_real_transforms.py +505 -0
  198. scipy/fft/_realtransforms.py +706 -0
  199. scipy/fft/_realtransforms_backend.py +63 -0
  200. scipy/fft/tests/__init__.py +0 -0
  201. scipy/fft/tests/mock_backend.py +96 -0
  202. scipy/fft/tests/test_backend.py +98 -0
  203. scipy/fft/tests/test_basic.py +504 -0
  204. scipy/fft/tests/test_fftlog.py +215 -0
  205. scipy/fft/tests/test_helper.py +558 -0
  206. scipy/fft/tests/test_multithreading.py +84 -0
  207. scipy/fft/tests/test_real_transforms.py +247 -0
  208. scipy/fftpack/__init__.py +103 -0
  209. scipy/fftpack/_basic.py +428 -0
  210. scipy/fftpack/_helper.py +115 -0
  211. scipy/fftpack/_pseudo_diffs.py +554 -0
  212. scipy/fftpack/_realtransforms.py +598 -0
  213. scipy/fftpack/basic.py +20 -0
  214. scipy/fftpack/convolve.cp311-win_arm64.lib +0 -0
  215. scipy/fftpack/convolve.cp311-win_arm64.pyd +0 -0
  216. scipy/fftpack/helper.py +19 -0
  217. scipy/fftpack/pseudo_diffs.py +22 -0
  218. scipy/fftpack/realtransforms.py +19 -0
  219. scipy/fftpack/tests/__init__.py +0 -0
  220. scipy/fftpack/tests/fftw_double_ref.npz +0 -0
  221. scipy/fftpack/tests/fftw_longdouble_ref.npz +0 -0
  222. scipy/fftpack/tests/fftw_single_ref.npz +0 -0
  223. scipy/fftpack/tests/test.npz +0 -0
  224. scipy/fftpack/tests/test_basic.py +877 -0
  225. scipy/fftpack/tests/test_helper.py +54 -0
  226. scipy/fftpack/tests/test_import.py +33 -0
  227. scipy/fftpack/tests/test_pseudo_diffs.py +388 -0
  228. scipy/fftpack/tests/test_real_transforms.py +836 -0
  229. scipy/integrate/__init__.py +122 -0
  230. scipy/integrate/_bvp.py +1160 -0
  231. scipy/integrate/_cubature.py +729 -0
  232. scipy/integrate/_dop.cp311-win_arm64.lib +0 -0
  233. scipy/integrate/_dop.cp311-win_arm64.pyd +0 -0
  234. scipy/integrate/_ivp/__init__.py +8 -0
  235. scipy/integrate/_ivp/base.py +290 -0
  236. scipy/integrate/_ivp/bdf.py +478 -0
  237. scipy/integrate/_ivp/common.py +451 -0
  238. scipy/integrate/_ivp/dop853_coefficients.py +193 -0
  239. scipy/integrate/_ivp/ivp.py +755 -0
  240. scipy/integrate/_ivp/lsoda.py +224 -0
  241. scipy/integrate/_ivp/radau.py +572 -0
  242. scipy/integrate/_ivp/rk.py +601 -0
  243. scipy/integrate/_ivp/tests/__init__.py +0 -0
  244. scipy/integrate/_ivp/tests/test_ivp.py +1287 -0
  245. scipy/integrate/_ivp/tests/test_rk.py +37 -0
  246. scipy/integrate/_lebedev.py +5450 -0
  247. scipy/integrate/_lsoda.cp311-win_arm64.lib +0 -0
  248. scipy/integrate/_lsoda.cp311-win_arm64.pyd +0 -0
  249. scipy/integrate/_ode.py +1395 -0
  250. scipy/integrate/_odepack.cp311-win_arm64.lib +0 -0
  251. scipy/integrate/_odepack.cp311-win_arm64.pyd +0 -0
  252. scipy/integrate/_odepack_py.py +273 -0
  253. scipy/integrate/_quad_vec.py +674 -0
  254. scipy/integrate/_quadpack.cp311-win_arm64.lib +0 -0
  255. scipy/integrate/_quadpack.cp311-win_arm64.pyd +0 -0
  256. scipy/integrate/_quadpack_py.py +1283 -0
  257. scipy/integrate/_quadrature.py +1336 -0
  258. scipy/integrate/_rules/__init__.py +12 -0
  259. scipy/integrate/_rules/_base.py +518 -0
  260. scipy/integrate/_rules/_gauss_kronrod.py +202 -0
  261. scipy/integrate/_rules/_gauss_legendre.py +62 -0
  262. scipy/integrate/_rules/_genz_malik.py +210 -0
  263. scipy/integrate/_tanhsinh.py +1385 -0
  264. scipy/integrate/_test_multivariate.cp311-win_arm64.lib +0 -0
  265. scipy/integrate/_test_multivariate.cp311-win_arm64.pyd +0 -0
  266. scipy/integrate/_test_odeint_banded.cp311-win_arm64.lib +0 -0
  267. scipy/integrate/_test_odeint_banded.cp311-win_arm64.pyd +0 -0
  268. scipy/integrate/_vode.cp311-win_arm64.lib +0 -0
  269. scipy/integrate/_vode.cp311-win_arm64.pyd +0 -0
  270. scipy/integrate/dop.py +15 -0
  271. scipy/integrate/lsoda.py +15 -0
  272. scipy/integrate/odepack.py +17 -0
  273. scipy/integrate/quadpack.py +23 -0
  274. scipy/integrate/tests/__init__.py +0 -0
  275. scipy/integrate/tests/test__quad_vec.py +211 -0
  276. scipy/integrate/tests/test_banded_ode_solvers.py +305 -0
  277. scipy/integrate/tests/test_bvp.py +714 -0
  278. scipy/integrate/tests/test_cubature.py +1375 -0
  279. scipy/integrate/tests/test_integrate.py +840 -0
  280. scipy/integrate/tests/test_odeint_jac.py +74 -0
  281. scipy/integrate/tests/test_quadpack.py +680 -0
  282. scipy/integrate/tests/test_quadrature.py +730 -0
  283. scipy/integrate/tests/test_tanhsinh.py +1171 -0
  284. scipy/integrate/vode.py +15 -0
  285. scipy/interpolate/__init__.py +228 -0
  286. scipy/interpolate/_bary_rational.py +715 -0
  287. scipy/interpolate/_bsplines.py +2469 -0
  288. scipy/interpolate/_cubic.py +973 -0
  289. scipy/interpolate/_dfitpack.cp311-win_arm64.lib +0 -0
  290. scipy/interpolate/_dfitpack.cp311-win_arm64.pyd +0 -0
  291. scipy/interpolate/_dierckx.cp311-win_arm64.lib +0 -0
  292. scipy/interpolate/_dierckx.cp311-win_arm64.pyd +0 -0
  293. scipy/interpolate/_fitpack.cp311-win_arm64.lib +0 -0
  294. scipy/interpolate/_fitpack.cp311-win_arm64.pyd +0 -0
  295. scipy/interpolate/_fitpack2.py +2397 -0
  296. scipy/interpolate/_fitpack_impl.py +811 -0
  297. scipy/interpolate/_fitpack_py.py +898 -0
  298. scipy/interpolate/_fitpack_repro.py +996 -0
  299. scipy/interpolate/_interpnd.cp311-win_arm64.lib +0 -0
  300. scipy/interpolate/_interpnd.cp311-win_arm64.pyd +0 -0
  301. scipy/interpolate/_interpolate.py +2266 -0
  302. scipy/interpolate/_ndbspline.py +415 -0
  303. scipy/interpolate/_ndgriddata.py +329 -0
  304. scipy/interpolate/_pade.py +67 -0
  305. scipy/interpolate/_polyint.py +1025 -0
  306. scipy/interpolate/_ppoly.cp311-win_arm64.lib +0 -0
  307. scipy/interpolate/_ppoly.cp311-win_arm64.pyd +0 -0
  308. scipy/interpolate/_rbf.py +290 -0
  309. scipy/interpolate/_rbfinterp.py +550 -0
  310. scipy/interpolate/_rbfinterp_pythran.cp311-win_arm64.lib +0 -0
  311. scipy/interpolate/_rbfinterp_pythran.cp311-win_arm64.pyd +0 -0
  312. scipy/interpolate/_rgi.py +764 -0
  313. scipy/interpolate/_rgi_cython.cp311-win_arm64.lib +0 -0
  314. scipy/interpolate/_rgi_cython.cp311-win_arm64.pyd +0 -0
  315. scipy/interpolate/dfitpack.py +24 -0
  316. scipy/interpolate/fitpack.py +31 -0
  317. scipy/interpolate/fitpack2.py +29 -0
  318. scipy/interpolate/interpnd.py +24 -0
  319. scipy/interpolate/interpolate.py +30 -0
  320. scipy/interpolate/ndgriddata.py +23 -0
  321. scipy/interpolate/polyint.py +24 -0
  322. scipy/interpolate/rbf.py +18 -0
  323. scipy/interpolate/tests/__init__.py +0 -0
  324. scipy/interpolate/tests/data/bug-1310.npz +0 -0
  325. scipy/interpolate/tests/data/estimate_gradients_hang.npy +0 -0
  326. scipy/interpolate/tests/data/gcvspl.npz +0 -0
  327. scipy/interpolate/tests/test_bary_rational.py +368 -0
  328. scipy/interpolate/tests/test_bsplines.py +3754 -0
  329. scipy/interpolate/tests/test_fitpack.py +519 -0
  330. scipy/interpolate/tests/test_fitpack2.py +1431 -0
  331. scipy/interpolate/tests/test_gil.py +64 -0
  332. scipy/interpolate/tests/test_interpnd.py +452 -0
  333. scipy/interpolate/tests/test_interpolate.py +2630 -0
  334. scipy/interpolate/tests/test_ndgriddata.py +308 -0
  335. scipy/interpolate/tests/test_pade.py +107 -0
  336. scipy/interpolate/tests/test_polyint.py +972 -0
  337. scipy/interpolate/tests/test_rbf.py +246 -0
  338. scipy/interpolate/tests/test_rbfinterp.py +534 -0
  339. scipy/interpolate/tests/test_rgi.py +1151 -0
  340. scipy/io/__init__.py +116 -0
  341. scipy/io/_fast_matrix_market/__init__.py +600 -0
  342. scipy/io/_fast_matrix_market/_fmm_core.cp311-win_arm64.lib +0 -0
  343. scipy/io/_fast_matrix_market/_fmm_core.cp311-win_arm64.pyd +0 -0
  344. scipy/io/_fortran.py +354 -0
  345. scipy/io/_harwell_boeing/__init__.py +7 -0
  346. scipy/io/_harwell_boeing/_fortran_format_parser.py +316 -0
  347. scipy/io/_harwell_boeing/hb.py +571 -0
  348. scipy/io/_harwell_boeing/tests/__init__.py +0 -0
  349. scipy/io/_harwell_boeing/tests/test_fortran_format.py +74 -0
  350. scipy/io/_harwell_boeing/tests/test_hb.py +70 -0
  351. scipy/io/_idl.py +917 -0
  352. scipy/io/_mmio.py +968 -0
  353. scipy/io/_netcdf.py +1104 -0
  354. scipy/io/_test_fortran.cp311-win_arm64.lib +0 -0
  355. scipy/io/_test_fortran.cp311-win_arm64.pyd +0 -0
  356. scipy/io/arff/__init__.py +28 -0
  357. scipy/io/arff/_arffread.py +873 -0
  358. scipy/io/arff/arffread.py +19 -0
  359. scipy/io/arff/tests/__init__.py +0 -0
  360. scipy/io/arff/tests/data/iris.arff +225 -0
  361. scipy/io/arff/tests/data/missing.arff +8 -0
  362. scipy/io/arff/tests/data/nodata.arff +11 -0
  363. scipy/io/arff/tests/data/quoted_nominal.arff +13 -0
  364. scipy/io/arff/tests/data/quoted_nominal_spaces.arff +13 -0
  365. scipy/io/arff/tests/data/test1.arff +10 -0
  366. scipy/io/arff/tests/data/test10.arff +8 -0
  367. scipy/io/arff/tests/data/test11.arff +11 -0
  368. scipy/io/arff/tests/data/test2.arff +15 -0
  369. scipy/io/arff/tests/data/test3.arff +6 -0
  370. scipy/io/arff/tests/data/test4.arff +11 -0
  371. scipy/io/arff/tests/data/test5.arff +26 -0
  372. scipy/io/arff/tests/data/test6.arff +12 -0
  373. scipy/io/arff/tests/data/test7.arff +15 -0
  374. scipy/io/arff/tests/data/test8.arff +12 -0
  375. scipy/io/arff/tests/data/test9.arff +14 -0
  376. scipy/io/arff/tests/test_arffread.py +421 -0
  377. scipy/io/harwell_boeing.py +17 -0
  378. scipy/io/idl.py +17 -0
  379. scipy/io/matlab/__init__.py +66 -0
  380. scipy/io/matlab/_byteordercodes.py +75 -0
  381. scipy/io/matlab/_mio.py +375 -0
  382. scipy/io/matlab/_mio4.py +632 -0
  383. scipy/io/matlab/_mio5.py +901 -0
  384. scipy/io/matlab/_mio5_params.py +281 -0
  385. scipy/io/matlab/_mio5_utils.cp311-win_arm64.lib +0 -0
  386. scipy/io/matlab/_mio5_utils.cp311-win_arm64.pyd +0 -0
  387. scipy/io/matlab/_mio_utils.cp311-win_arm64.lib +0 -0
  388. scipy/io/matlab/_mio_utils.cp311-win_arm64.pyd +0 -0
  389. scipy/io/matlab/_miobase.py +435 -0
  390. scipy/io/matlab/_streams.cp311-win_arm64.lib +0 -0
  391. scipy/io/matlab/_streams.cp311-win_arm64.pyd +0 -0
  392. scipy/io/matlab/byteordercodes.py +17 -0
  393. scipy/io/matlab/mio.py +16 -0
  394. scipy/io/matlab/mio4.py +17 -0
  395. scipy/io/matlab/mio5.py +19 -0
  396. scipy/io/matlab/mio5_params.py +18 -0
  397. scipy/io/matlab/mio5_utils.py +17 -0
  398. scipy/io/matlab/mio_utils.py +17 -0
  399. scipy/io/matlab/miobase.py +16 -0
  400. scipy/io/matlab/streams.py +16 -0
  401. scipy/io/matlab/tests/__init__.py +0 -0
  402. scipy/io/matlab/tests/data/bad_miuint32.mat +0 -0
  403. scipy/io/matlab/tests/data/bad_miutf8_array_name.mat +0 -0
  404. scipy/io/matlab/tests/data/big_endian.mat +0 -0
  405. scipy/io/matlab/tests/data/broken_utf8.mat +0 -0
  406. scipy/io/matlab/tests/data/corrupted_zlib_checksum.mat +0 -0
  407. scipy/io/matlab/tests/data/corrupted_zlib_data.mat +0 -0
  408. scipy/io/matlab/tests/data/debigged_m4.mat +0 -0
  409. scipy/io/matlab/tests/data/japanese_utf8.txt +5 -0
  410. scipy/io/matlab/tests/data/little_endian.mat +0 -0
  411. scipy/io/matlab/tests/data/logical_sparse.mat +0 -0
  412. scipy/io/matlab/tests/data/malformed1.mat +0 -0
  413. scipy/io/matlab/tests/data/miuint32_for_miint32.mat +0 -0
  414. scipy/io/matlab/tests/data/miutf8_array_name.mat +0 -0
  415. scipy/io/matlab/tests/data/nasty_duplicate_fieldnames.mat +0 -0
  416. scipy/io/matlab/tests/data/one_by_zero_char.mat +0 -0
  417. scipy/io/matlab/tests/data/parabola.mat +0 -0
  418. scipy/io/matlab/tests/data/single_empty_string.mat +0 -0
  419. scipy/io/matlab/tests/data/some_functions.mat +0 -0
  420. scipy/io/matlab/tests/data/sqr.mat +0 -0
  421. scipy/io/matlab/tests/data/test3dmatrix_6.1_SOL2.mat +0 -0
  422. scipy/io/matlab/tests/data/test3dmatrix_6.5.1_GLNX86.mat +0 -0
  423. scipy/io/matlab/tests/data/test3dmatrix_7.1_GLNX86.mat +0 -0
  424. scipy/io/matlab/tests/data/test3dmatrix_7.4_GLNX86.mat +0 -0
  425. scipy/io/matlab/tests/data/test_empty_struct.mat +0 -0
  426. scipy/io/matlab/tests/data/test_mat4_le_floats.mat +0 -0
  427. scipy/io/matlab/tests/data/test_skip_variable.mat +0 -0
  428. scipy/io/matlab/tests/data/testbool_8_WIN64.mat +0 -0
  429. scipy/io/matlab/tests/data/testcell_6.1_SOL2.mat +0 -0
  430. scipy/io/matlab/tests/data/testcell_6.5.1_GLNX86.mat +0 -0
  431. scipy/io/matlab/tests/data/testcell_7.1_GLNX86.mat +0 -0
  432. scipy/io/matlab/tests/data/testcell_7.4_GLNX86.mat +0 -0
  433. scipy/io/matlab/tests/data/testcellnest_6.1_SOL2.mat +0 -0
  434. scipy/io/matlab/tests/data/testcellnest_6.5.1_GLNX86.mat +0 -0
  435. scipy/io/matlab/tests/data/testcellnest_7.1_GLNX86.mat +0 -0
  436. scipy/io/matlab/tests/data/testcellnest_7.4_GLNX86.mat +0 -0
  437. scipy/io/matlab/tests/data/testcomplex_4.2c_SOL2.mat +0 -0
  438. scipy/io/matlab/tests/data/testcomplex_6.1_SOL2.mat +0 -0
  439. scipy/io/matlab/tests/data/testcomplex_6.5.1_GLNX86.mat +0 -0
  440. scipy/io/matlab/tests/data/testcomplex_7.1_GLNX86.mat +0 -0
  441. scipy/io/matlab/tests/data/testcomplex_7.4_GLNX86.mat +0 -0
  442. scipy/io/matlab/tests/data/testdouble_4.2c_SOL2.mat +0 -0
  443. scipy/io/matlab/tests/data/testdouble_6.1_SOL2.mat +0 -0
  444. scipy/io/matlab/tests/data/testdouble_6.5.1_GLNX86.mat +0 -0
  445. scipy/io/matlab/tests/data/testdouble_7.1_GLNX86.mat +0 -0
  446. scipy/io/matlab/tests/data/testdouble_7.4_GLNX86.mat +0 -0
  447. scipy/io/matlab/tests/data/testemptycell_5.3_SOL2.mat +0 -0
  448. scipy/io/matlab/tests/data/testemptycell_6.5.1_GLNX86.mat +0 -0
  449. scipy/io/matlab/tests/data/testemptycell_7.1_GLNX86.mat +0 -0
  450. scipy/io/matlab/tests/data/testemptycell_7.4_GLNX86.mat +0 -0
  451. scipy/io/matlab/tests/data/testfunc_7.4_GLNX86.mat +0 -0
  452. scipy/io/matlab/tests/data/testhdf5_7.4_GLNX86.mat +0 -0
  453. scipy/io/matlab/tests/data/testmatrix_4.2c_SOL2.mat +0 -0
  454. scipy/io/matlab/tests/data/testmatrix_6.1_SOL2.mat +0 -0
  455. scipy/io/matlab/tests/data/testmatrix_6.5.1_GLNX86.mat +0 -0
  456. scipy/io/matlab/tests/data/testmatrix_7.1_GLNX86.mat +0 -0
  457. scipy/io/matlab/tests/data/testmatrix_7.4_GLNX86.mat +0 -0
  458. scipy/io/matlab/tests/data/testminus_4.2c_SOL2.mat +0 -0
  459. scipy/io/matlab/tests/data/testminus_6.1_SOL2.mat +0 -0
  460. scipy/io/matlab/tests/data/testminus_6.5.1_GLNX86.mat +0 -0
  461. scipy/io/matlab/tests/data/testminus_7.1_GLNX86.mat +0 -0
  462. scipy/io/matlab/tests/data/testminus_7.4_GLNX86.mat +0 -0
  463. scipy/io/matlab/tests/data/testmulti_4.2c_SOL2.mat +0 -0
  464. scipy/io/matlab/tests/data/testmulti_7.1_GLNX86.mat +0 -0
  465. scipy/io/matlab/tests/data/testmulti_7.4_GLNX86.mat +0 -0
  466. scipy/io/matlab/tests/data/testobject_6.1_SOL2.mat +0 -0
  467. scipy/io/matlab/tests/data/testobject_6.5.1_GLNX86.mat +0 -0
  468. scipy/io/matlab/tests/data/testobject_7.1_GLNX86.mat +0 -0
  469. scipy/io/matlab/tests/data/testobject_7.4_GLNX86.mat +0 -0
  470. scipy/io/matlab/tests/data/testonechar_4.2c_SOL2.mat +0 -0
  471. scipy/io/matlab/tests/data/testonechar_6.1_SOL2.mat +0 -0
  472. scipy/io/matlab/tests/data/testonechar_6.5.1_GLNX86.mat +0 -0
  473. scipy/io/matlab/tests/data/testonechar_7.1_GLNX86.mat +0 -0
  474. scipy/io/matlab/tests/data/testonechar_7.4_GLNX86.mat +0 -0
  475. scipy/io/matlab/tests/data/testscalarcell_7.4_GLNX86.mat +0 -0
  476. scipy/io/matlab/tests/data/testsimplecell.mat +0 -0
  477. scipy/io/matlab/tests/data/testsparse_4.2c_SOL2.mat +0 -0
  478. scipy/io/matlab/tests/data/testsparse_6.1_SOL2.mat +0 -0
  479. scipy/io/matlab/tests/data/testsparse_6.5.1_GLNX86.mat +0 -0
  480. scipy/io/matlab/tests/data/testsparse_7.1_GLNX86.mat +0 -0
  481. scipy/io/matlab/tests/data/testsparse_7.4_GLNX86.mat +0 -0
  482. scipy/io/matlab/tests/data/testsparsecomplex_4.2c_SOL2.mat +0 -0
  483. scipy/io/matlab/tests/data/testsparsecomplex_6.1_SOL2.mat +0 -0
  484. scipy/io/matlab/tests/data/testsparsecomplex_6.5.1_GLNX86.mat +0 -0
  485. scipy/io/matlab/tests/data/testsparsecomplex_7.1_GLNX86.mat +0 -0
  486. scipy/io/matlab/tests/data/testsparsecomplex_7.4_GLNX86.mat +0 -0
  487. scipy/io/matlab/tests/data/testsparsefloat_7.4_GLNX86.mat +0 -0
  488. scipy/io/matlab/tests/data/teststring_4.2c_SOL2.mat +0 -0
  489. scipy/io/matlab/tests/data/teststring_6.1_SOL2.mat +0 -0
  490. scipy/io/matlab/tests/data/teststring_6.5.1_GLNX86.mat +0 -0
  491. scipy/io/matlab/tests/data/teststring_7.1_GLNX86.mat +0 -0
  492. scipy/io/matlab/tests/data/teststring_7.4_GLNX86.mat +0 -0
  493. scipy/io/matlab/tests/data/teststringarray_4.2c_SOL2.mat +0 -0
  494. scipy/io/matlab/tests/data/teststringarray_6.1_SOL2.mat +0 -0
  495. scipy/io/matlab/tests/data/teststringarray_6.5.1_GLNX86.mat +0 -0
  496. scipy/io/matlab/tests/data/teststringarray_7.1_GLNX86.mat +0 -0
  497. scipy/io/matlab/tests/data/teststringarray_7.4_GLNX86.mat +0 -0
  498. scipy/io/matlab/tests/data/teststruct_6.1_SOL2.mat +0 -0
  499. scipy/io/matlab/tests/data/teststruct_6.5.1_GLNX86.mat +0 -0
  500. scipy/io/matlab/tests/data/teststruct_7.1_GLNX86.mat +0 -0
  501. scipy/io/matlab/tests/data/teststruct_7.4_GLNX86.mat +0 -0
  502. scipy/io/matlab/tests/data/teststructarr_6.1_SOL2.mat +0 -0
  503. scipy/io/matlab/tests/data/teststructarr_6.5.1_GLNX86.mat +0 -0
  504. scipy/io/matlab/tests/data/teststructarr_7.1_GLNX86.mat +0 -0
  505. scipy/io/matlab/tests/data/teststructarr_7.4_GLNX86.mat +0 -0
  506. scipy/io/matlab/tests/data/teststructnest_6.1_SOL2.mat +0 -0
  507. scipy/io/matlab/tests/data/teststructnest_6.5.1_GLNX86.mat +0 -0
  508. scipy/io/matlab/tests/data/teststructnest_7.1_GLNX86.mat +0 -0
  509. scipy/io/matlab/tests/data/teststructnest_7.4_GLNX86.mat +0 -0
  510. scipy/io/matlab/tests/data/testunicode_7.1_GLNX86.mat +0 -0
  511. scipy/io/matlab/tests/data/testunicode_7.4_GLNX86.mat +0 -0
  512. scipy/io/matlab/tests/data/testvec_4_GLNX86.mat +0 -0
  513. scipy/io/matlab/tests/test_byteordercodes.py +29 -0
  514. scipy/io/matlab/tests/test_mio.py +1399 -0
  515. scipy/io/matlab/tests/test_mio5_utils.py +179 -0
  516. scipy/io/matlab/tests/test_mio_funcs.py +51 -0
  517. scipy/io/matlab/tests/test_mio_utils.py +45 -0
  518. scipy/io/matlab/tests/test_miobase.py +32 -0
  519. scipy/io/matlab/tests/test_pathological.py +33 -0
  520. scipy/io/matlab/tests/test_streams.py +241 -0
  521. scipy/io/mmio.py +17 -0
  522. scipy/io/netcdf.py +17 -0
  523. scipy/io/tests/__init__.py +0 -0
  524. scipy/io/tests/data/Transparent Busy.ani +0 -0
  525. scipy/io/tests/data/array_float32_1d.sav +0 -0
  526. scipy/io/tests/data/array_float32_2d.sav +0 -0
  527. scipy/io/tests/data/array_float32_3d.sav +0 -0
  528. scipy/io/tests/data/array_float32_4d.sav +0 -0
  529. scipy/io/tests/data/array_float32_5d.sav +0 -0
  530. scipy/io/tests/data/array_float32_6d.sav +0 -0
  531. scipy/io/tests/data/array_float32_7d.sav +0 -0
  532. scipy/io/tests/data/array_float32_8d.sav +0 -0
  533. scipy/io/tests/data/array_float32_pointer_1d.sav +0 -0
  534. scipy/io/tests/data/array_float32_pointer_2d.sav +0 -0
  535. scipy/io/tests/data/array_float32_pointer_3d.sav +0 -0
  536. scipy/io/tests/data/array_float32_pointer_4d.sav +0 -0
  537. scipy/io/tests/data/array_float32_pointer_5d.sav +0 -0
  538. scipy/io/tests/data/array_float32_pointer_6d.sav +0 -0
  539. scipy/io/tests/data/array_float32_pointer_7d.sav +0 -0
  540. scipy/io/tests/data/array_float32_pointer_8d.sav +0 -0
  541. scipy/io/tests/data/example_1.nc +0 -0
  542. scipy/io/tests/data/example_2.nc +0 -0
  543. scipy/io/tests/data/example_3_maskedvals.nc +0 -0
  544. scipy/io/tests/data/fortran-3x3d-2i.dat +0 -0
  545. scipy/io/tests/data/fortran-mixed.dat +0 -0
  546. scipy/io/tests/data/fortran-sf8-11x1x10.dat +0 -0
  547. scipy/io/tests/data/fortran-sf8-15x10x22.dat +0 -0
  548. scipy/io/tests/data/fortran-sf8-1x1x1.dat +0 -0
  549. scipy/io/tests/data/fortran-sf8-1x1x5.dat +0 -0
  550. scipy/io/tests/data/fortran-sf8-1x1x7.dat +0 -0
  551. scipy/io/tests/data/fortran-sf8-1x3x5.dat +0 -0
  552. scipy/io/tests/data/fortran-si4-11x1x10.dat +0 -0
  553. scipy/io/tests/data/fortran-si4-15x10x22.dat +0 -0
  554. scipy/io/tests/data/fortran-si4-1x1x1.dat +0 -0
  555. scipy/io/tests/data/fortran-si4-1x1x5.dat +0 -0
  556. scipy/io/tests/data/fortran-si4-1x1x7.dat +0 -0
  557. scipy/io/tests/data/fortran-si4-1x3x5.dat +0 -0
  558. scipy/io/tests/data/invalid_pointer.sav +0 -0
  559. scipy/io/tests/data/null_pointer.sav +0 -0
  560. scipy/io/tests/data/scalar_byte.sav +0 -0
  561. scipy/io/tests/data/scalar_byte_descr.sav +0 -0
  562. scipy/io/tests/data/scalar_complex32.sav +0 -0
  563. scipy/io/tests/data/scalar_complex64.sav +0 -0
  564. scipy/io/tests/data/scalar_float32.sav +0 -0
  565. scipy/io/tests/data/scalar_float64.sav +0 -0
  566. scipy/io/tests/data/scalar_heap_pointer.sav +0 -0
  567. scipy/io/tests/data/scalar_int16.sav +0 -0
  568. scipy/io/tests/data/scalar_int32.sav +0 -0
  569. scipy/io/tests/data/scalar_int64.sav +0 -0
  570. scipy/io/tests/data/scalar_string.sav +0 -0
  571. scipy/io/tests/data/scalar_uint16.sav +0 -0
  572. scipy/io/tests/data/scalar_uint32.sav +0 -0
  573. scipy/io/tests/data/scalar_uint64.sav +0 -0
  574. scipy/io/tests/data/struct_arrays.sav +0 -0
  575. scipy/io/tests/data/struct_arrays_byte_idl80.sav +0 -0
  576. scipy/io/tests/data/struct_arrays_replicated.sav +0 -0
  577. scipy/io/tests/data/struct_arrays_replicated_3d.sav +0 -0
  578. scipy/io/tests/data/struct_inherit.sav +0 -0
  579. scipy/io/tests/data/struct_pointer_arrays.sav +0 -0
  580. scipy/io/tests/data/struct_pointer_arrays_replicated.sav +0 -0
  581. scipy/io/tests/data/struct_pointer_arrays_replicated_3d.sav +0 -0
  582. scipy/io/tests/data/struct_pointers.sav +0 -0
  583. scipy/io/tests/data/struct_pointers_replicated.sav +0 -0
  584. scipy/io/tests/data/struct_pointers_replicated_3d.sav +0 -0
  585. scipy/io/tests/data/struct_scalars.sav +0 -0
  586. scipy/io/tests/data/struct_scalars_replicated.sav +0 -0
  587. scipy/io/tests/data/struct_scalars_replicated_3d.sav +0 -0
  588. scipy/io/tests/data/test-1234Hz-le-1ch-10S-20bit-extra.wav +0 -0
  589. scipy/io/tests/data/test-44100Hz-2ch-32bit-float-be.wav +0 -0
  590. scipy/io/tests/data/test-44100Hz-2ch-32bit-float-le.wav +0 -0
  591. scipy/io/tests/data/test-44100Hz-be-1ch-4bytes.wav +0 -0
  592. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-early-eof-no-data.wav +0 -0
  593. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-early-eof.wav +0 -0
  594. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-incomplete-chunk.wav +0 -0
  595. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-rf64.wav +0 -0
  596. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes.wav +0 -0
  597. scipy/io/tests/data/test-48000Hz-2ch-64bit-float-le-wavex.wav +0 -0
  598. scipy/io/tests/data/test-8000Hz-be-3ch-5S-24bit.wav +0 -0
  599. scipy/io/tests/data/test-8000Hz-le-1ch-1byte-ulaw.wav +0 -0
  600. scipy/io/tests/data/test-8000Hz-le-2ch-1byteu.wav +0 -0
  601. scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit-inconsistent.wav +0 -0
  602. scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit-rf64.wav +0 -0
  603. scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit.wav +0 -0
  604. scipy/io/tests/data/test-8000Hz-le-3ch-5S-36bit.wav +0 -0
  605. scipy/io/tests/data/test-8000Hz-le-3ch-5S-45bit.wav +0 -0
  606. scipy/io/tests/data/test-8000Hz-le-3ch-5S-53bit.wav +0 -0
  607. scipy/io/tests/data/test-8000Hz-le-3ch-5S-64bit.wav +0 -0
  608. scipy/io/tests/data/test-8000Hz-le-4ch-9S-12bit.wav +0 -0
  609. scipy/io/tests/data/test-8000Hz-le-5ch-9S-5bit.wav +0 -0
  610. scipy/io/tests/data/various_compressed.sav +0 -0
  611. scipy/io/tests/test_fortran.py +264 -0
  612. scipy/io/tests/test_idl.py +483 -0
  613. scipy/io/tests/test_mmio.py +831 -0
  614. scipy/io/tests/test_netcdf.py +550 -0
  615. scipy/io/tests/test_paths.py +93 -0
  616. scipy/io/tests/test_wavfile.py +501 -0
  617. scipy/io/wavfile.py +938 -0
  618. scipy/linalg/__init__.pxd +1 -0
  619. scipy/linalg/__init__.py +236 -0
  620. scipy/linalg/_basic.py +2146 -0
  621. scipy/linalg/_blas_subroutines.h +164 -0
  622. scipy/linalg/_cythonized_array_utils.cp311-win_arm64.lib +0 -0
  623. scipy/linalg/_cythonized_array_utils.cp311-win_arm64.pyd +0 -0
  624. scipy/linalg/_cythonized_array_utils.pxd +40 -0
  625. scipy/linalg/_cythonized_array_utils.pyi +16 -0
  626. scipy/linalg/_decomp.py +1645 -0
  627. scipy/linalg/_decomp_cholesky.py +413 -0
  628. scipy/linalg/_decomp_cossin.py +236 -0
  629. scipy/linalg/_decomp_interpolative.cp311-win_arm64.lib +0 -0
  630. scipy/linalg/_decomp_interpolative.cp311-win_arm64.pyd +0 -0
  631. scipy/linalg/_decomp_ldl.py +356 -0
  632. scipy/linalg/_decomp_lu.py +401 -0
  633. scipy/linalg/_decomp_lu_cython.cp311-win_arm64.lib +0 -0
  634. scipy/linalg/_decomp_lu_cython.cp311-win_arm64.pyd +0 -0
  635. scipy/linalg/_decomp_lu_cython.pyi +6 -0
  636. scipy/linalg/_decomp_polar.py +113 -0
  637. scipy/linalg/_decomp_qr.py +494 -0
  638. scipy/linalg/_decomp_qz.py +452 -0
  639. scipy/linalg/_decomp_schur.py +336 -0
  640. scipy/linalg/_decomp_svd.py +545 -0
  641. scipy/linalg/_decomp_update.cp311-win_arm64.lib +0 -0
  642. scipy/linalg/_decomp_update.cp311-win_arm64.pyd +0 -0
  643. scipy/linalg/_expm_frechet.py +417 -0
  644. scipy/linalg/_fblas.cp311-win_arm64.lib +0 -0
  645. scipy/linalg/_fblas.cp311-win_arm64.pyd +0 -0
  646. scipy/linalg/_flapack.cp311-win_arm64.lib +0 -0
  647. scipy/linalg/_flapack.cp311-win_arm64.pyd +0 -0
  648. scipy/linalg/_lapack_subroutines.h +1521 -0
  649. scipy/linalg/_linalg_pythran.cp311-win_arm64.lib +0 -0
  650. scipy/linalg/_linalg_pythran.cp311-win_arm64.pyd +0 -0
  651. scipy/linalg/_matfuncs.py +1050 -0
  652. scipy/linalg/_matfuncs_expm.cp311-win_arm64.lib +0 -0
  653. scipy/linalg/_matfuncs_expm.cp311-win_arm64.pyd +0 -0
  654. scipy/linalg/_matfuncs_expm.pyi +6 -0
  655. scipy/linalg/_matfuncs_inv_ssq.py +886 -0
  656. scipy/linalg/_matfuncs_schur_sqrtm.cp311-win_arm64.lib +0 -0
  657. scipy/linalg/_matfuncs_schur_sqrtm.cp311-win_arm64.pyd +0 -0
  658. scipy/linalg/_matfuncs_sqrtm.py +107 -0
  659. scipy/linalg/_matfuncs_sqrtm_triu.cp311-win_arm64.lib +0 -0
  660. scipy/linalg/_matfuncs_sqrtm_triu.cp311-win_arm64.pyd +0 -0
  661. scipy/linalg/_misc.py +191 -0
  662. scipy/linalg/_procrustes.py +113 -0
  663. scipy/linalg/_sketches.py +189 -0
  664. scipy/linalg/_solve_toeplitz.cp311-win_arm64.lib +0 -0
  665. scipy/linalg/_solve_toeplitz.cp311-win_arm64.pyd +0 -0
  666. scipy/linalg/_solvers.py +862 -0
  667. scipy/linalg/_special_matrices.py +1322 -0
  668. scipy/linalg/_testutils.py +65 -0
  669. scipy/linalg/basic.py +23 -0
  670. scipy/linalg/blas.py +495 -0
  671. scipy/linalg/cython_blas.cp311-win_arm64.lib +0 -0
  672. scipy/linalg/cython_blas.cp311-win_arm64.pyd +0 -0
  673. scipy/linalg/cython_blas.pxd +169 -0
  674. scipy/linalg/cython_blas.pyx +1432 -0
  675. scipy/linalg/cython_lapack.cp311-win_arm64.lib +0 -0
  676. scipy/linalg/cython_lapack.cp311-win_arm64.pyd +0 -0
  677. scipy/linalg/cython_lapack.pxd +1528 -0
  678. scipy/linalg/cython_lapack.pyx +12045 -0
  679. scipy/linalg/decomp.py +23 -0
  680. scipy/linalg/decomp_cholesky.py +21 -0
  681. scipy/linalg/decomp_lu.py +21 -0
  682. scipy/linalg/decomp_qr.py +20 -0
  683. scipy/linalg/decomp_schur.py +21 -0
  684. scipy/linalg/decomp_svd.py +21 -0
  685. scipy/linalg/interpolative.py +989 -0
  686. scipy/linalg/lapack.py +1081 -0
  687. scipy/linalg/matfuncs.py +23 -0
  688. scipy/linalg/misc.py +21 -0
  689. scipy/linalg/special_matrices.py +22 -0
  690. scipy/linalg/tests/__init__.py +0 -0
  691. scipy/linalg/tests/_cython_examples/extending.pyx +23 -0
  692. scipy/linalg/tests/_cython_examples/meson.build +34 -0
  693. scipy/linalg/tests/data/carex_15_data.npz +0 -0
  694. scipy/linalg/tests/data/carex_18_data.npz +0 -0
  695. scipy/linalg/tests/data/carex_19_data.npz +0 -0
  696. scipy/linalg/tests/data/carex_20_data.npz +0 -0
  697. scipy/linalg/tests/data/carex_6_data.npz +0 -0
  698. scipy/linalg/tests/data/gendare_20170120_data.npz +0 -0
  699. scipy/linalg/tests/test_basic.py +2074 -0
  700. scipy/linalg/tests/test_batch.py +588 -0
  701. scipy/linalg/tests/test_blas.py +1127 -0
  702. scipy/linalg/tests/test_cython_blas.py +118 -0
  703. scipy/linalg/tests/test_cython_lapack.py +22 -0
  704. scipy/linalg/tests/test_cythonized_array_utils.py +130 -0
  705. scipy/linalg/tests/test_decomp.py +3189 -0
  706. scipy/linalg/tests/test_decomp_cholesky.py +268 -0
  707. scipy/linalg/tests/test_decomp_cossin.py +314 -0
  708. scipy/linalg/tests/test_decomp_ldl.py +137 -0
  709. scipy/linalg/tests/test_decomp_lu.py +308 -0
  710. scipy/linalg/tests/test_decomp_polar.py +110 -0
  711. scipy/linalg/tests/test_decomp_update.py +1701 -0
  712. scipy/linalg/tests/test_extending.py +46 -0
  713. scipy/linalg/tests/test_fblas.py +607 -0
  714. scipy/linalg/tests/test_interpolative.py +232 -0
  715. scipy/linalg/tests/test_lapack.py +3620 -0
  716. scipy/linalg/tests/test_matfuncs.py +1125 -0
  717. scipy/linalg/tests/test_matmul_toeplitz.py +136 -0
  718. scipy/linalg/tests/test_procrustes.py +214 -0
  719. scipy/linalg/tests/test_sketches.py +118 -0
  720. scipy/linalg/tests/test_solve_toeplitz.py +150 -0
  721. scipy/linalg/tests/test_solvers.py +844 -0
  722. scipy/linalg/tests/test_special_matrices.py +636 -0
  723. scipy/misc/__init__.py +6 -0
  724. scipy/misc/common.py +6 -0
  725. scipy/misc/doccer.py +6 -0
  726. scipy/ndimage/__init__.py +174 -0
  727. scipy/ndimage/_ctest.cp311-win_arm64.lib +0 -0
  728. scipy/ndimage/_ctest.cp311-win_arm64.pyd +0 -0
  729. scipy/ndimage/_cytest.cp311-win_arm64.lib +0 -0
  730. scipy/ndimage/_cytest.cp311-win_arm64.pyd +0 -0
  731. scipy/ndimage/_delegators.py +303 -0
  732. scipy/ndimage/_filters.py +2422 -0
  733. scipy/ndimage/_fourier.py +306 -0
  734. scipy/ndimage/_interpolation.py +1033 -0
  735. scipy/ndimage/_measurements.py +1689 -0
  736. scipy/ndimage/_morphology.py +2634 -0
  737. scipy/ndimage/_nd_image.cp311-win_arm64.lib +0 -0
  738. scipy/ndimage/_nd_image.cp311-win_arm64.pyd +0 -0
  739. scipy/ndimage/_ndimage_api.py +16 -0
  740. scipy/ndimage/_ni_docstrings.py +214 -0
  741. scipy/ndimage/_ni_label.cp311-win_arm64.lib +0 -0
  742. scipy/ndimage/_ni_label.cp311-win_arm64.pyd +0 -0
  743. scipy/ndimage/_ni_support.py +139 -0
  744. scipy/ndimage/_rank_filter_1d.cp311-win_arm64.lib +0 -0
  745. scipy/ndimage/_rank_filter_1d.cp311-win_arm64.pyd +0 -0
  746. scipy/ndimage/_support_alternative_backends.py +84 -0
  747. scipy/ndimage/filters.py +27 -0
  748. scipy/ndimage/fourier.py +21 -0
  749. scipy/ndimage/interpolation.py +22 -0
  750. scipy/ndimage/measurements.py +24 -0
  751. scipy/ndimage/morphology.py +27 -0
  752. scipy/ndimage/tests/__init__.py +12 -0
  753. scipy/ndimage/tests/data/label_inputs.txt +21 -0
  754. scipy/ndimage/tests/data/label_results.txt +294 -0
  755. scipy/ndimage/tests/data/label_strels.txt +42 -0
  756. scipy/ndimage/tests/dots.png +0 -0
  757. scipy/ndimage/tests/test_c_api.py +102 -0
  758. scipy/ndimage/tests/test_datatypes.py +67 -0
  759. scipy/ndimage/tests/test_filters.py +3083 -0
  760. scipy/ndimage/tests/test_fourier.py +187 -0
  761. scipy/ndimage/tests/test_interpolation.py +1491 -0
  762. scipy/ndimage/tests/test_measurements.py +1592 -0
  763. scipy/ndimage/tests/test_morphology.py +2950 -0
  764. scipy/ndimage/tests/test_ni_support.py +78 -0
  765. scipy/ndimage/tests/test_splines.py +70 -0
  766. scipy/odr/__init__.py +131 -0
  767. scipy/odr/__odrpack.cp311-win_arm64.lib +0 -0
  768. scipy/odr/__odrpack.cp311-win_arm64.pyd +0 -0
  769. scipy/odr/_add_newdocs.py +34 -0
  770. scipy/odr/_models.py +315 -0
  771. scipy/odr/_odrpack.py +1154 -0
  772. scipy/odr/models.py +20 -0
  773. scipy/odr/odrpack.py +21 -0
  774. scipy/odr/tests/__init__.py +0 -0
  775. scipy/odr/tests/test_odr.py +607 -0
  776. scipy/optimize/__init__.pxd +1 -0
  777. scipy/optimize/__init__.py +460 -0
  778. scipy/optimize/_basinhopping.py +741 -0
  779. scipy/optimize/_bglu_dense.cp311-win_arm64.lib +0 -0
  780. scipy/optimize/_bglu_dense.cp311-win_arm64.pyd +0 -0
  781. scipy/optimize/_bracket.py +706 -0
  782. scipy/optimize/_chandrupatla.py +551 -0
  783. scipy/optimize/_cobyla_py.py +297 -0
  784. scipy/optimize/_cobyqa_py.py +72 -0
  785. scipy/optimize/_constraints.py +598 -0
  786. scipy/optimize/_dcsrch.py +728 -0
  787. scipy/optimize/_differentiable_functions.py +835 -0
  788. scipy/optimize/_differentialevolution.py +1970 -0
  789. scipy/optimize/_direct.cp311-win_arm64.lib +0 -0
  790. scipy/optimize/_direct.cp311-win_arm64.pyd +0 -0
  791. scipy/optimize/_direct_py.py +280 -0
  792. scipy/optimize/_dual_annealing.py +732 -0
  793. scipy/optimize/_elementwise.py +798 -0
  794. scipy/optimize/_group_columns.cp311-win_arm64.lib +0 -0
  795. scipy/optimize/_group_columns.cp311-win_arm64.pyd +0 -0
  796. scipy/optimize/_hessian_update_strategy.py +479 -0
  797. scipy/optimize/_highspy/__init__.py +0 -0
  798. scipy/optimize/_highspy/_core.cp311-win_arm64.lib +0 -0
  799. scipy/optimize/_highspy/_core.cp311-win_arm64.pyd +0 -0
  800. scipy/optimize/_highspy/_highs_options.cp311-win_arm64.lib +0 -0
  801. scipy/optimize/_highspy/_highs_options.cp311-win_arm64.pyd +0 -0
  802. scipy/optimize/_highspy/_highs_wrapper.py +338 -0
  803. scipy/optimize/_isotonic.py +157 -0
  804. scipy/optimize/_lbfgsb.cp311-win_arm64.lib +0 -0
  805. scipy/optimize/_lbfgsb.cp311-win_arm64.pyd +0 -0
  806. scipy/optimize/_lbfgsb_py.py +634 -0
  807. scipy/optimize/_linesearch.py +896 -0
  808. scipy/optimize/_linprog.py +733 -0
  809. scipy/optimize/_linprog_doc.py +1434 -0
  810. scipy/optimize/_linprog_highs.py +422 -0
  811. scipy/optimize/_linprog_ip.py +1141 -0
  812. scipy/optimize/_linprog_rs.py +572 -0
  813. scipy/optimize/_linprog_simplex.py +663 -0
  814. scipy/optimize/_linprog_util.py +1521 -0
  815. scipy/optimize/_lsap.cp311-win_arm64.lib +0 -0
  816. scipy/optimize/_lsap.cp311-win_arm64.pyd +0 -0
  817. scipy/optimize/_lsq/__init__.py +5 -0
  818. scipy/optimize/_lsq/bvls.py +183 -0
  819. scipy/optimize/_lsq/common.py +731 -0
  820. scipy/optimize/_lsq/dogbox.py +345 -0
  821. scipy/optimize/_lsq/givens_elimination.cp311-win_arm64.lib +0 -0
  822. scipy/optimize/_lsq/givens_elimination.cp311-win_arm64.pyd +0 -0
  823. scipy/optimize/_lsq/least_squares.py +1044 -0
  824. scipy/optimize/_lsq/lsq_linear.py +361 -0
  825. scipy/optimize/_lsq/trf.py +587 -0
  826. scipy/optimize/_lsq/trf_linear.py +249 -0
  827. scipy/optimize/_milp.py +394 -0
  828. scipy/optimize/_minimize.py +1199 -0
  829. scipy/optimize/_minpack.cp311-win_arm64.lib +0 -0
  830. scipy/optimize/_minpack.cp311-win_arm64.pyd +0 -0
  831. scipy/optimize/_minpack_py.py +1178 -0
  832. scipy/optimize/_moduleTNC.cp311-win_arm64.lib +0 -0
  833. scipy/optimize/_moduleTNC.cp311-win_arm64.pyd +0 -0
  834. scipy/optimize/_nnls.py +96 -0
  835. scipy/optimize/_nonlin.py +1634 -0
  836. scipy/optimize/_numdiff.py +963 -0
  837. scipy/optimize/_optimize.py +4169 -0
  838. scipy/optimize/_pava_pybind.cp311-win_arm64.lib +0 -0
  839. scipy/optimize/_pava_pybind.cp311-win_arm64.pyd +0 -0
  840. scipy/optimize/_qap.py +760 -0
  841. scipy/optimize/_remove_redundancy.py +522 -0
  842. scipy/optimize/_root.py +732 -0
  843. scipy/optimize/_root_scalar.py +538 -0
  844. scipy/optimize/_shgo.py +1606 -0
  845. scipy/optimize/_shgo_lib/__init__.py +0 -0
  846. scipy/optimize/_shgo_lib/_complex.py +1225 -0
  847. scipy/optimize/_shgo_lib/_vertex.py +460 -0
  848. scipy/optimize/_slsqp_py.py +603 -0
  849. scipy/optimize/_slsqplib.cp311-win_arm64.lib +0 -0
  850. scipy/optimize/_slsqplib.cp311-win_arm64.pyd +0 -0
  851. scipy/optimize/_spectral.py +260 -0
  852. scipy/optimize/_tnc.py +438 -0
  853. scipy/optimize/_trlib/__init__.py +12 -0
  854. scipy/optimize/_trlib/_trlib.cp311-win_arm64.lib +0 -0
  855. scipy/optimize/_trlib/_trlib.cp311-win_arm64.pyd +0 -0
  856. scipy/optimize/_trustregion.py +318 -0
  857. scipy/optimize/_trustregion_constr/__init__.py +6 -0
  858. scipy/optimize/_trustregion_constr/canonical_constraint.py +390 -0
  859. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +231 -0
  860. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +584 -0
  861. scipy/optimize/_trustregion_constr/projections.py +411 -0
  862. scipy/optimize/_trustregion_constr/qp_subproblem.py +637 -0
  863. scipy/optimize/_trustregion_constr/report.py +49 -0
  864. scipy/optimize/_trustregion_constr/tests/__init__.py +0 -0
  865. scipy/optimize/_trustregion_constr/tests/test_canonical_constraint.py +296 -0
  866. scipy/optimize/_trustregion_constr/tests/test_nested_minimize.py +39 -0
  867. scipy/optimize/_trustregion_constr/tests/test_projections.py +214 -0
  868. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +645 -0
  869. scipy/optimize/_trustregion_constr/tests/test_report.py +34 -0
  870. scipy/optimize/_trustregion_constr/tr_interior_point.py +361 -0
  871. scipy/optimize/_trustregion_dogleg.py +122 -0
  872. scipy/optimize/_trustregion_exact.py +437 -0
  873. scipy/optimize/_trustregion_krylov.py +65 -0
  874. scipy/optimize/_trustregion_ncg.py +126 -0
  875. scipy/optimize/_tstutils.py +972 -0
  876. scipy/optimize/_zeros.cp311-win_arm64.lib +0 -0
  877. scipy/optimize/_zeros.cp311-win_arm64.pyd +0 -0
  878. scipy/optimize/_zeros_py.py +1475 -0
  879. scipy/optimize/cobyla.py +19 -0
  880. scipy/optimize/cython_optimize/__init__.py +133 -0
  881. scipy/optimize/cython_optimize/_zeros.cp311-win_arm64.lib +0 -0
  882. scipy/optimize/cython_optimize/_zeros.cp311-win_arm64.pyd +0 -0
  883. scipy/optimize/cython_optimize/_zeros.pxd +33 -0
  884. scipy/optimize/cython_optimize/c_zeros.pxd +26 -0
  885. scipy/optimize/cython_optimize.pxd +11 -0
  886. scipy/optimize/elementwise.py +38 -0
  887. scipy/optimize/lbfgsb.py +23 -0
  888. scipy/optimize/linesearch.py +18 -0
  889. scipy/optimize/minpack.py +27 -0
  890. scipy/optimize/minpack2.py +17 -0
  891. scipy/optimize/moduleTNC.py +19 -0
  892. scipy/optimize/nonlin.py +29 -0
  893. scipy/optimize/optimize.py +40 -0
  894. scipy/optimize/slsqp.py +22 -0
  895. scipy/optimize/tests/__init__.py +0 -0
  896. scipy/optimize/tests/_cython_examples/extending.pyx +43 -0
  897. scipy/optimize/tests/_cython_examples/meson.build +32 -0
  898. scipy/optimize/tests/test__basinhopping.py +535 -0
  899. scipy/optimize/tests/test__differential_evolution.py +1703 -0
  900. scipy/optimize/tests/test__dual_annealing.py +416 -0
  901. scipy/optimize/tests/test__linprog_clean_inputs.py +312 -0
  902. scipy/optimize/tests/test__numdiff.py +885 -0
  903. scipy/optimize/tests/test__remove_redundancy.py +228 -0
  904. scipy/optimize/tests/test__root.py +124 -0
  905. scipy/optimize/tests/test__shgo.py +1164 -0
  906. scipy/optimize/tests/test__spectral.py +226 -0
  907. scipy/optimize/tests/test_bracket.py +896 -0
  908. scipy/optimize/tests/test_chandrupatla.py +982 -0
  909. scipy/optimize/tests/test_cobyla.py +195 -0
  910. scipy/optimize/tests/test_cobyqa.py +252 -0
  911. scipy/optimize/tests/test_constraint_conversion.py +286 -0
  912. scipy/optimize/tests/test_constraints.py +255 -0
  913. scipy/optimize/tests/test_cython_optimize.py +92 -0
  914. scipy/optimize/tests/test_differentiable_functions.py +1025 -0
  915. scipy/optimize/tests/test_direct.py +321 -0
  916. scipy/optimize/tests/test_extending.py +28 -0
  917. scipy/optimize/tests/test_hessian_update_strategy.py +300 -0
  918. scipy/optimize/tests/test_isotonic_regression.py +167 -0
  919. scipy/optimize/tests/test_lbfgsb_hessinv.py +65 -0
  920. scipy/optimize/tests/test_lbfgsb_setulb.py +122 -0
  921. scipy/optimize/tests/test_least_squares.py +986 -0
  922. scipy/optimize/tests/test_linear_assignment.py +116 -0
  923. scipy/optimize/tests/test_linesearch.py +328 -0
  924. scipy/optimize/tests/test_linprog.py +2577 -0
  925. scipy/optimize/tests/test_lsq_common.py +297 -0
  926. scipy/optimize/tests/test_lsq_linear.py +287 -0
  927. scipy/optimize/tests/test_milp.py +459 -0
  928. scipy/optimize/tests/test_minimize_constrained.py +845 -0
  929. scipy/optimize/tests/test_minpack.py +1194 -0
  930. scipy/optimize/tests/test_nnls.py +469 -0
  931. scipy/optimize/tests/test_nonlin.py +572 -0
  932. scipy/optimize/tests/test_optimize.py +3344 -0
  933. scipy/optimize/tests/test_quadratic_assignment.py +455 -0
  934. scipy/optimize/tests/test_regression.py +40 -0
  935. scipy/optimize/tests/test_slsqp.py +645 -0
  936. scipy/optimize/tests/test_tnc.py +345 -0
  937. scipy/optimize/tests/test_trustregion.py +110 -0
  938. scipy/optimize/tests/test_trustregion_exact.py +351 -0
  939. scipy/optimize/tests/test_trustregion_krylov.py +170 -0
  940. scipy/optimize/tests/test_zeros.py +998 -0
  941. scipy/optimize/tnc.py +22 -0
  942. scipy/optimize/zeros.py +26 -0
  943. scipy/signal/__init__.py +316 -0
  944. scipy/signal/_arraytools.py +264 -0
  945. scipy/signal/_czt.py +575 -0
  946. scipy/signal/_delegators.py +568 -0
  947. scipy/signal/_filter_design.py +5893 -0
  948. scipy/signal/_fir_filter_design.py +1458 -0
  949. scipy/signal/_lti_conversion.py +534 -0
  950. scipy/signal/_ltisys.py +3546 -0
  951. scipy/signal/_max_len_seq.py +139 -0
  952. scipy/signal/_max_len_seq_inner.cp311-win_arm64.lib +0 -0
  953. scipy/signal/_max_len_seq_inner.cp311-win_arm64.pyd +0 -0
  954. scipy/signal/_peak_finding.py +1310 -0
  955. scipy/signal/_peak_finding_utils.cp311-win_arm64.lib +0 -0
  956. scipy/signal/_peak_finding_utils.cp311-win_arm64.pyd +0 -0
  957. scipy/signal/_polyutils.py +172 -0
  958. scipy/signal/_savitzky_golay.py +357 -0
  959. scipy/signal/_short_time_fft.py +2228 -0
  960. scipy/signal/_signal_api.py +30 -0
  961. scipy/signal/_signaltools.py +5309 -0
  962. scipy/signal/_sigtools.cp311-win_arm64.lib +0 -0
  963. scipy/signal/_sigtools.cp311-win_arm64.pyd +0 -0
  964. scipy/signal/_sosfilt.cp311-win_arm64.lib +0 -0
  965. scipy/signal/_sosfilt.cp311-win_arm64.pyd +0 -0
  966. scipy/signal/_spectral_py.py +2471 -0
  967. scipy/signal/_spline.cp311-win_arm64.lib +0 -0
  968. scipy/signal/_spline.cp311-win_arm64.pyd +0 -0
  969. scipy/signal/_spline.pyi +34 -0
  970. scipy/signal/_spline_filters.py +848 -0
  971. scipy/signal/_support_alternative_backends.py +73 -0
  972. scipy/signal/_upfirdn.py +219 -0
  973. scipy/signal/_upfirdn_apply.cp311-win_arm64.lib +0 -0
  974. scipy/signal/_upfirdn_apply.cp311-win_arm64.pyd +0 -0
  975. scipy/signal/_waveforms.py +687 -0
  976. scipy/signal/_wavelets.py +29 -0
  977. scipy/signal/bsplines.py +21 -0
  978. scipy/signal/filter_design.py +28 -0
  979. scipy/signal/fir_filter_design.py +21 -0
  980. scipy/signal/lti_conversion.py +20 -0
  981. scipy/signal/ltisys.py +25 -0
  982. scipy/signal/signaltools.py +27 -0
  983. scipy/signal/spectral.py +21 -0
  984. scipy/signal/spline.py +18 -0
  985. scipy/signal/tests/__init__.py +0 -0
  986. scipy/signal/tests/_scipy_spectral_test_shim.py +311 -0
  987. scipy/signal/tests/mpsig.py +122 -0
  988. scipy/signal/tests/test_array_tools.py +111 -0
  989. scipy/signal/tests/test_bsplines.py +365 -0
  990. scipy/signal/tests/test_cont2discrete.py +424 -0
  991. scipy/signal/tests/test_czt.py +221 -0
  992. scipy/signal/tests/test_dltisys.py +599 -0
  993. scipy/signal/tests/test_filter_design.py +4744 -0
  994. scipy/signal/tests/test_fir_filter_design.py +851 -0
  995. scipy/signal/tests/test_ltisys.py +1225 -0
  996. scipy/signal/tests/test_max_len_seq.py +71 -0
  997. scipy/signal/tests/test_peak_finding.py +915 -0
  998. scipy/signal/tests/test_result_type.py +51 -0
  999. scipy/signal/tests/test_savitzky_golay.py +363 -0
  1000. scipy/signal/tests/test_short_time_fft.py +1107 -0
  1001. scipy/signal/tests/test_signaltools.py +4735 -0
  1002. scipy/signal/tests/test_spectral.py +2141 -0
  1003. scipy/signal/tests/test_splines.py +427 -0
  1004. scipy/signal/tests/test_upfirdn.py +322 -0
  1005. scipy/signal/tests/test_waveforms.py +400 -0
  1006. scipy/signal/tests/test_wavelets.py +59 -0
  1007. scipy/signal/tests/test_windows.py +987 -0
  1008. scipy/signal/waveforms.py +20 -0
  1009. scipy/signal/wavelets.py +17 -0
  1010. scipy/signal/windows/__init__.py +52 -0
  1011. scipy/signal/windows/_windows.py +2513 -0
  1012. scipy/signal/windows/windows.py +23 -0
  1013. scipy/sparse/__init__.py +350 -0
  1014. scipy/sparse/_base.py +1613 -0
  1015. scipy/sparse/_bsr.py +880 -0
  1016. scipy/sparse/_compressed.py +1328 -0
  1017. scipy/sparse/_construct.py +1454 -0
  1018. scipy/sparse/_coo.py +1581 -0
  1019. scipy/sparse/_csc.py +367 -0
  1020. scipy/sparse/_csparsetools.cp311-win_arm64.lib +0 -0
  1021. scipy/sparse/_csparsetools.cp311-win_arm64.pyd +0 -0
  1022. scipy/sparse/_csr.py +558 -0
  1023. scipy/sparse/_data.py +569 -0
  1024. scipy/sparse/_dia.py +677 -0
  1025. scipy/sparse/_dok.py +669 -0
  1026. scipy/sparse/_extract.py +178 -0
  1027. scipy/sparse/_index.py +444 -0
  1028. scipy/sparse/_lil.py +632 -0
  1029. scipy/sparse/_matrix.py +169 -0
  1030. scipy/sparse/_matrix_io.py +167 -0
  1031. scipy/sparse/_sparsetools.cp311-win_arm64.lib +0 -0
  1032. scipy/sparse/_sparsetools.cp311-win_arm64.pyd +0 -0
  1033. scipy/sparse/_spfuncs.py +76 -0
  1034. scipy/sparse/_sputils.py +632 -0
  1035. scipy/sparse/base.py +24 -0
  1036. scipy/sparse/bsr.py +22 -0
  1037. scipy/sparse/compressed.py +20 -0
  1038. scipy/sparse/construct.py +38 -0
  1039. scipy/sparse/coo.py +23 -0
  1040. scipy/sparse/csc.py +22 -0
  1041. scipy/sparse/csgraph/__init__.py +210 -0
  1042. scipy/sparse/csgraph/_flow.cp311-win_arm64.lib +0 -0
  1043. scipy/sparse/csgraph/_flow.cp311-win_arm64.pyd +0 -0
  1044. scipy/sparse/csgraph/_laplacian.py +563 -0
  1045. scipy/sparse/csgraph/_matching.cp311-win_arm64.lib +0 -0
  1046. scipy/sparse/csgraph/_matching.cp311-win_arm64.pyd +0 -0
  1047. scipy/sparse/csgraph/_min_spanning_tree.cp311-win_arm64.lib +0 -0
  1048. scipy/sparse/csgraph/_min_spanning_tree.cp311-win_arm64.pyd +0 -0
  1049. scipy/sparse/csgraph/_reordering.cp311-win_arm64.lib +0 -0
  1050. scipy/sparse/csgraph/_reordering.cp311-win_arm64.pyd +0 -0
  1051. scipy/sparse/csgraph/_shortest_path.cp311-win_arm64.lib +0 -0
  1052. scipy/sparse/csgraph/_shortest_path.cp311-win_arm64.pyd +0 -0
  1053. scipy/sparse/csgraph/_tools.cp311-win_arm64.lib +0 -0
  1054. scipy/sparse/csgraph/_tools.cp311-win_arm64.pyd +0 -0
  1055. scipy/sparse/csgraph/_traversal.cp311-win_arm64.lib +0 -0
  1056. scipy/sparse/csgraph/_traversal.cp311-win_arm64.pyd +0 -0
  1057. scipy/sparse/csgraph/_validation.py +66 -0
  1058. scipy/sparse/csgraph/tests/__init__.py +0 -0
  1059. scipy/sparse/csgraph/tests/test_connected_components.py +119 -0
  1060. scipy/sparse/csgraph/tests/test_conversions.py +61 -0
  1061. scipy/sparse/csgraph/tests/test_flow.py +209 -0
  1062. scipy/sparse/csgraph/tests/test_graph_laplacian.py +368 -0
  1063. scipy/sparse/csgraph/tests/test_matching.py +307 -0
  1064. scipy/sparse/csgraph/tests/test_pydata_sparse.py +197 -0
  1065. scipy/sparse/csgraph/tests/test_reordering.py +70 -0
  1066. scipy/sparse/csgraph/tests/test_shortest_path.py +540 -0
  1067. scipy/sparse/csgraph/tests/test_spanning_tree.py +66 -0
  1068. scipy/sparse/csgraph/tests/test_traversal.py +148 -0
  1069. scipy/sparse/csr.py +22 -0
  1070. scipy/sparse/data.py +18 -0
  1071. scipy/sparse/dia.py +22 -0
  1072. scipy/sparse/dok.py +22 -0
  1073. scipy/sparse/extract.py +23 -0
  1074. scipy/sparse/lil.py +22 -0
  1075. scipy/sparse/linalg/__init__.py +148 -0
  1076. scipy/sparse/linalg/_dsolve/__init__.py +71 -0
  1077. scipy/sparse/linalg/_dsolve/_add_newdocs.py +147 -0
  1078. scipy/sparse/linalg/_dsolve/_superlu.cp311-win_arm64.lib +0 -0
  1079. scipy/sparse/linalg/_dsolve/_superlu.cp311-win_arm64.pyd +0 -0
  1080. scipy/sparse/linalg/_dsolve/linsolve.py +882 -0
  1081. scipy/sparse/linalg/_dsolve/tests/__init__.py +0 -0
  1082. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +928 -0
  1083. scipy/sparse/linalg/_eigen/__init__.py +22 -0
  1084. scipy/sparse/linalg/_eigen/_svds.py +540 -0
  1085. scipy/sparse/linalg/_eigen/_svds_doc.py +382 -0
  1086. scipy/sparse/linalg/_eigen/arpack/COPYING +45 -0
  1087. scipy/sparse/linalg/_eigen/arpack/__init__.py +20 -0
  1088. scipy/sparse/linalg/_eigen/arpack/_arpack.cp311-win_arm64.lib +0 -0
  1089. scipy/sparse/linalg/_eigen/arpack/_arpack.cp311-win_arm64.pyd +0 -0
  1090. scipy/sparse/linalg/_eigen/arpack/arpack.py +1706 -0
  1091. scipy/sparse/linalg/_eigen/arpack/tests/__init__.py +0 -0
  1092. scipy/sparse/linalg/_eigen/arpack/tests/test_arpack.py +717 -0
  1093. scipy/sparse/linalg/_eigen/lobpcg/__init__.py +16 -0
  1094. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +1110 -0
  1095. scipy/sparse/linalg/_eigen/lobpcg/tests/__init__.py +0 -0
  1096. scipy/sparse/linalg/_eigen/lobpcg/tests/test_lobpcg.py +725 -0
  1097. scipy/sparse/linalg/_eigen/tests/__init__.py +0 -0
  1098. scipy/sparse/linalg/_eigen/tests/test_svds.py +886 -0
  1099. scipy/sparse/linalg/_expm_multiply.py +816 -0
  1100. scipy/sparse/linalg/_interface.py +920 -0
  1101. scipy/sparse/linalg/_isolve/__init__.py +20 -0
  1102. scipy/sparse/linalg/_isolve/_gcrotmk.py +503 -0
  1103. scipy/sparse/linalg/_isolve/iterative.py +1051 -0
  1104. scipy/sparse/linalg/_isolve/lgmres.py +230 -0
  1105. scipy/sparse/linalg/_isolve/lsmr.py +486 -0
  1106. scipy/sparse/linalg/_isolve/lsqr.py +589 -0
  1107. scipy/sparse/linalg/_isolve/minres.py +372 -0
  1108. scipy/sparse/linalg/_isolve/tests/__init__.py +0 -0
  1109. scipy/sparse/linalg/_isolve/tests/test_gcrotmk.py +183 -0
  1110. scipy/sparse/linalg/_isolve/tests/test_iterative.py +809 -0
  1111. scipy/sparse/linalg/_isolve/tests/test_lgmres.py +225 -0
  1112. scipy/sparse/linalg/_isolve/tests/test_lsmr.py +185 -0
  1113. scipy/sparse/linalg/_isolve/tests/test_lsqr.py +120 -0
  1114. scipy/sparse/linalg/_isolve/tests/test_minres.py +97 -0
  1115. scipy/sparse/linalg/_isolve/tests/test_utils.py +9 -0
  1116. scipy/sparse/linalg/_isolve/tfqmr.py +179 -0
  1117. scipy/sparse/linalg/_isolve/utils.py +121 -0
  1118. scipy/sparse/linalg/_matfuncs.py +940 -0
  1119. scipy/sparse/linalg/_norm.py +195 -0
  1120. scipy/sparse/linalg/_onenormest.py +467 -0
  1121. scipy/sparse/linalg/_propack/_cpropack.cp311-win_arm64.lib +0 -0
  1122. scipy/sparse/linalg/_propack/_cpropack.cp311-win_arm64.pyd +0 -0
  1123. scipy/sparse/linalg/_propack/_dpropack.cp311-win_arm64.lib +0 -0
  1124. scipy/sparse/linalg/_propack/_dpropack.cp311-win_arm64.pyd +0 -0
  1125. scipy/sparse/linalg/_propack/_spropack.cp311-win_arm64.lib +0 -0
  1126. scipy/sparse/linalg/_propack/_spropack.cp311-win_arm64.pyd +0 -0
  1127. scipy/sparse/linalg/_propack/_zpropack.cp311-win_arm64.lib +0 -0
  1128. scipy/sparse/linalg/_propack/_zpropack.cp311-win_arm64.pyd +0 -0
  1129. scipy/sparse/linalg/_special_sparse_arrays.py +949 -0
  1130. scipy/sparse/linalg/_svdp.py +309 -0
  1131. scipy/sparse/linalg/dsolve.py +22 -0
  1132. scipy/sparse/linalg/eigen.py +21 -0
  1133. scipy/sparse/linalg/interface.py +20 -0
  1134. scipy/sparse/linalg/isolve.py +22 -0
  1135. scipy/sparse/linalg/matfuncs.py +18 -0
  1136. scipy/sparse/linalg/tests/__init__.py +0 -0
  1137. scipy/sparse/linalg/tests/propack_test_data.npz +0 -0
  1138. scipy/sparse/linalg/tests/test_expm_multiply.py +367 -0
  1139. scipy/sparse/linalg/tests/test_interface.py +561 -0
  1140. scipy/sparse/linalg/tests/test_matfuncs.py +592 -0
  1141. scipy/sparse/linalg/tests/test_norm.py +154 -0
  1142. scipy/sparse/linalg/tests/test_onenormest.py +252 -0
  1143. scipy/sparse/linalg/tests/test_propack.py +165 -0
  1144. scipy/sparse/linalg/tests/test_pydata_sparse.py +272 -0
  1145. scipy/sparse/linalg/tests/test_special_sparse_arrays.py +337 -0
  1146. scipy/sparse/sparsetools.py +17 -0
  1147. scipy/sparse/spfuncs.py +17 -0
  1148. scipy/sparse/sputils.py +17 -0
  1149. scipy/sparse/tests/__init__.py +0 -0
  1150. scipy/sparse/tests/data/csc_py2.npz +0 -0
  1151. scipy/sparse/tests/data/csc_py3.npz +0 -0
  1152. scipy/sparse/tests/test_arithmetic1d.py +341 -0
  1153. scipy/sparse/tests/test_array_api.py +561 -0
  1154. scipy/sparse/tests/test_base.py +5870 -0
  1155. scipy/sparse/tests/test_common1d.py +447 -0
  1156. scipy/sparse/tests/test_construct.py +872 -0
  1157. scipy/sparse/tests/test_coo.py +1119 -0
  1158. scipy/sparse/tests/test_csc.py +98 -0
  1159. scipy/sparse/tests/test_csr.py +214 -0
  1160. scipy/sparse/tests/test_dok.py +209 -0
  1161. scipy/sparse/tests/test_extract.py +51 -0
  1162. scipy/sparse/tests/test_indexing1d.py +603 -0
  1163. scipy/sparse/tests/test_matrix_io.py +109 -0
  1164. scipy/sparse/tests/test_minmax1d.py +128 -0
  1165. scipy/sparse/tests/test_sparsetools.py +344 -0
  1166. scipy/sparse/tests/test_spfuncs.py +97 -0
  1167. scipy/sparse/tests/test_sputils.py +424 -0
  1168. scipy/spatial/__init__.py +129 -0
  1169. scipy/spatial/_ckdtree.cp311-win_arm64.lib +0 -0
  1170. scipy/spatial/_ckdtree.cp311-win_arm64.pyd +0 -0
  1171. scipy/spatial/_distance_pybind.cp311-win_arm64.lib +0 -0
  1172. scipy/spatial/_distance_pybind.cp311-win_arm64.pyd +0 -0
  1173. scipy/spatial/_distance_wrap.cp311-win_arm64.lib +0 -0
  1174. scipy/spatial/_distance_wrap.cp311-win_arm64.pyd +0 -0
  1175. scipy/spatial/_geometric_slerp.py +238 -0
  1176. scipy/spatial/_hausdorff.cp311-win_arm64.lib +0 -0
  1177. scipy/spatial/_hausdorff.cp311-win_arm64.pyd +0 -0
  1178. scipy/spatial/_kdtree.py +920 -0
  1179. scipy/spatial/_plotutils.py +274 -0
  1180. scipy/spatial/_procrustes.py +132 -0
  1181. scipy/spatial/_qhull.cp311-win_arm64.lib +0 -0
  1182. scipy/spatial/_qhull.cp311-win_arm64.pyd +0 -0
  1183. scipy/spatial/_qhull.pyi +213 -0
  1184. scipy/spatial/_spherical_voronoi.py +341 -0
  1185. scipy/spatial/_voronoi.cp311-win_arm64.lib +0 -0
  1186. scipy/spatial/_voronoi.cp311-win_arm64.pyd +0 -0
  1187. scipy/spatial/_voronoi.pyi +4 -0
  1188. scipy/spatial/ckdtree.py +18 -0
  1189. scipy/spatial/distance.py +3147 -0
  1190. scipy/spatial/distance.pyi +210 -0
  1191. scipy/spatial/kdtree.py +25 -0
  1192. scipy/spatial/qhull.py +25 -0
  1193. scipy/spatial/qhull_src/COPYING_QHULL.txt +39 -0
  1194. scipy/spatial/tests/__init__.py +0 -0
  1195. scipy/spatial/tests/data/cdist-X1.txt +10 -0
  1196. scipy/spatial/tests/data/cdist-X2.txt +20 -0
  1197. scipy/spatial/tests/data/degenerate_pointset.npz +0 -0
  1198. scipy/spatial/tests/data/iris.txt +150 -0
  1199. scipy/spatial/tests/data/pdist-boolean-inp.txt +20 -0
  1200. scipy/spatial/tests/data/pdist-chebyshev-ml-iris.txt +1 -0
  1201. scipy/spatial/tests/data/pdist-chebyshev-ml.txt +1 -0
  1202. scipy/spatial/tests/data/pdist-cityblock-ml-iris.txt +1 -0
  1203. scipy/spatial/tests/data/pdist-cityblock-ml.txt +1 -0
  1204. scipy/spatial/tests/data/pdist-correlation-ml-iris.txt +1 -0
  1205. scipy/spatial/tests/data/pdist-correlation-ml.txt +1 -0
  1206. scipy/spatial/tests/data/pdist-cosine-ml-iris.txt +1 -0
  1207. scipy/spatial/tests/data/pdist-cosine-ml.txt +1 -0
  1208. scipy/spatial/tests/data/pdist-double-inp.txt +20 -0
  1209. scipy/spatial/tests/data/pdist-euclidean-ml-iris.txt +1 -0
  1210. scipy/spatial/tests/data/pdist-euclidean-ml.txt +1 -0
  1211. scipy/spatial/tests/data/pdist-hamming-ml.txt +1 -0
  1212. scipy/spatial/tests/data/pdist-jaccard-ml.txt +1 -0
  1213. scipy/spatial/tests/data/pdist-jensenshannon-ml-iris.txt +1 -0
  1214. scipy/spatial/tests/data/pdist-jensenshannon-ml.txt +1 -0
  1215. scipy/spatial/tests/data/pdist-minkowski-3.2-ml-iris.txt +1 -0
  1216. scipy/spatial/tests/data/pdist-minkowski-3.2-ml.txt +1 -0
  1217. scipy/spatial/tests/data/pdist-minkowski-5.8-ml-iris.txt +1 -0
  1218. scipy/spatial/tests/data/pdist-seuclidean-ml-iris.txt +1 -0
  1219. scipy/spatial/tests/data/pdist-seuclidean-ml.txt +1 -0
  1220. scipy/spatial/tests/data/pdist-spearman-ml.txt +1 -0
  1221. scipy/spatial/tests/data/random-bool-data.txt +100 -0
  1222. scipy/spatial/tests/data/random-double-data.txt +100 -0
  1223. scipy/spatial/tests/data/random-int-data.txt +100 -0
  1224. scipy/spatial/tests/data/random-uint-data.txt +100 -0
  1225. scipy/spatial/tests/data/selfdual-4d-polytope.txt +27 -0
  1226. scipy/spatial/tests/test__plotutils.py +91 -0
  1227. scipy/spatial/tests/test__procrustes.py +116 -0
  1228. scipy/spatial/tests/test_distance.py +2389 -0
  1229. scipy/spatial/tests/test_hausdorff.py +199 -0
  1230. scipy/spatial/tests/test_kdtree.py +1536 -0
  1231. scipy/spatial/tests/test_qhull.py +1313 -0
  1232. scipy/spatial/tests/test_slerp.py +417 -0
  1233. scipy/spatial/tests/test_spherical_voronoi.py +358 -0
  1234. scipy/spatial/transform/__init__.py +31 -0
  1235. scipy/spatial/transform/_rigid_transform.cp311-win_arm64.lib +0 -0
  1236. scipy/spatial/transform/_rigid_transform.cp311-win_arm64.pyd +0 -0
  1237. scipy/spatial/transform/_rotation.cp311-win_arm64.lib +0 -0
  1238. scipy/spatial/transform/_rotation.cp311-win_arm64.pyd +0 -0
  1239. scipy/spatial/transform/_rotation_groups.py +140 -0
  1240. scipy/spatial/transform/_rotation_spline.py +460 -0
  1241. scipy/spatial/transform/rotation.py +21 -0
  1242. scipy/spatial/transform/tests/__init__.py +0 -0
  1243. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  1244. scipy/spatial/transform/tests/test_rotation.py +2569 -0
  1245. scipy/spatial/transform/tests/test_rotation_groups.py +169 -0
  1246. scipy/spatial/transform/tests/test_rotation_spline.py +183 -0
  1247. scipy/special/__init__.pxd +1 -0
  1248. scipy/special/__init__.py +841 -0
  1249. scipy/special/_add_newdocs.py +9961 -0
  1250. scipy/special/_basic.py +3576 -0
  1251. scipy/special/_comb.cp311-win_arm64.lib +0 -0
  1252. scipy/special/_comb.cp311-win_arm64.pyd +0 -0
  1253. scipy/special/_ellip_harm.py +214 -0
  1254. scipy/special/_ellip_harm_2.cp311-win_arm64.lib +0 -0
  1255. scipy/special/_ellip_harm_2.cp311-win_arm64.pyd +0 -0
  1256. scipy/special/_gufuncs.cp311-win_arm64.lib +0 -0
  1257. scipy/special/_gufuncs.cp311-win_arm64.pyd +0 -0
  1258. scipy/special/_input_validation.py +17 -0
  1259. scipy/special/_lambertw.py +149 -0
  1260. scipy/special/_logsumexp.py +426 -0
  1261. scipy/special/_mptestutils.py +453 -0
  1262. scipy/special/_multiufuncs.py +610 -0
  1263. scipy/special/_orthogonal.py +2592 -0
  1264. scipy/special/_orthogonal.pyi +330 -0
  1265. scipy/special/_precompute/__init__.py +0 -0
  1266. scipy/special/_precompute/cosine_cdf.py +17 -0
  1267. scipy/special/_precompute/expn_asy.py +54 -0
  1268. scipy/special/_precompute/gammainc_asy.py +116 -0
  1269. scipy/special/_precompute/gammainc_data.py +124 -0
  1270. scipy/special/_precompute/hyp2f1_data.py +484 -0
  1271. scipy/special/_precompute/lambertw.py +68 -0
  1272. scipy/special/_precompute/loggamma.py +43 -0
  1273. scipy/special/_precompute/struve_convergence.py +131 -0
  1274. scipy/special/_precompute/utils.py +38 -0
  1275. scipy/special/_precompute/wright_bessel.py +342 -0
  1276. scipy/special/_precompute/wright_bessel_data.py +152 -0
  1277. scipy/special/_precompute/wrightomega.py +41 -0
  1278. scipy/special/_precompute/zetac.py +27 -0
  1279. scipy/special/_sf_error.py +15 -0
  1280. scipy/special/_specfun.cp311-win_arm64.lib +0 -0
  1281. scipy/special/_specfun.cp311-win_arm64.pyd +0 -0
  1282. scipy/special/_special_ufuncs.cp311-win_arm64.lib +0 -0
  1283. scipy/special/_special_ufuncs.cp311-win_arm64.pyd +0 -0
  1284. scipy/special/_spfun_stats.py +106 -0
  1285. scipy/special/_spherical_bessel.py +397 -0
  1286. scipy/special/_support_alternative_backends.py +295 -0
  1287. scipy/special/_test_internal.cp311-win_arm64.lib +0 -0
  1288. scipy/special/_test_internal.cp311-win_arm64.pyd +0 -0
  1289. scipy/special/_test_internal.pyi +9 -0
  1290. scipy/special/_testutils.py +321 -0
  1291. scipy/special/_ufuncs.cp311-win_arm64.lib +0 -0
  1292. scipy/special/_ufuncs.cp311-win_arm64.pyd +0 -0
  1293. scipy/special/_ufuncs.pyi +522 -0
  1294. scipy/special/_ufuncs.pyx +13173 -0
  1295. scipy/special/_ufuncs_cxx.cp311-win_arm64.lib +0 -0
  1296. scipy/special/_ufuncs_cxx.cp311-win_arm64.pyd +0 -0
  1297. scipy/special/_ufuncs_cxx.pxd +142 -0
  1298. scipy/special/_ufuncs_cxx.pyx +427 -0
  1299. scipy/special/_ufuncs_cxx_defs.h +147 -0
  1300. scipy/special/_ufuncs_defs.h +57 -0
  1301. scipy/special/add_newdocs.py +15 -0
  1302. scipy/special/basic.py +87 -0
  1303. scipy/special/cython_special.cp311-win_arm64.lib +0 -0
  1304. scipy/special/cython_special.cp311-win_arm64.pyd +0 -0
  1305. scipy/special/cython_special.pxd +259 -0
  1306. scipy/special/cython_special.pyi +3 -0
  1307. scipy/special/orthogonal.py +45 -0
  1308. scipy/special/sf_error.py +20 -0
  1309. scipy/special/specfun.py +24 -0
  1310. scipy/special/spfun_stats.py +17 -0
  1311. scipy/special/tests/__init__.py +0 -0
  1312. scipy/special/tests/_cython_examples/extending.pyx +12 -0
  1313. scipy/special/tests/_cython_examples/meson.build +34 -0
  1314. scipy/special/tests/data/__init__.py +0 -0
  1315. scipy/special/tests/data/boost.npz +0 -0
  1316. scipy/special/tests/data/gsl.npz +0 -0
  1317. scipy/special/tests/data/local.npz +0 -0
  1318. scipy/special/tests/test_basic.py +4815 -0
  1319. scipy/special/tests/test_bdtr.py +112 -0
  1320. scipy/special/tests/test_boost_ufuncs.py +64 -0
  1321. scipy/special/tests/test_boxcox.py +125 -0
  1322. scipy/special/tests/test_cdflib.py +712 -0
  1323. scipy/special/tests/test_cdft_asymptotic.py +49 -0
  1324. scipy/special/tests/test_cephes_intp_cast.py +29 -0
  1325. scipy/special/tests/test_cosine_distr.py +83 -0
  1326. scipy/special/tests/test_cython_special.py +363 -0
  1327. scipy/special/tests/test_data.py +719 -0
  1328. scipy/special/tests/test_dd.py +42 -0
  1329. scipy/special/tests/test_digamma.py +45 -0
  1330. scipy/special/tests/test_ellip_harm.py +278 -0
  1331. scipy/special/tests/test_erfinv.py +89 -0
  1332. scipy/special/tests/test_exponential_integrals.py +118 -0
  1333. scipy/special/tests/test_extending.py +28 -0
  1334. scipy/special/tests/test_faddeeva.py +85 -0
  1335. scipy/special/tests/test_gamma.py +12 -0
  1336. scipy/special/tests/test_gammainc.py +152 -0
  1337. scipy/special/tests/test_hyp2f1.py +2566 -0
  1338. scipy/special/tests/test_hypergeometric.py +234 -0
  1339. scipy/special/tests/test_iv_ratio.py +249 -0
  1340. scipy/special/tests/test_kolmogorov.py +491 -0
  1341. scipy/special/tests/test_lambertw.py +109 -0
  1342. scipy/special/tests/test_legendre.py +1518 -0
  1343. scipy/special/tests/test_log1mexp.py +85 -0
  1344. scipy/special/tests/test_loggamma.py +70 -0
  1345. scipy/special/tests/test_logit.py +162 -0
  1346. scipy/special/tests/test_logsumexp.py +469 -0
  1347. scipy/special/tests/test_mpmath.py +2293 -0
  1348. scipy/special/tests/test_nan_inputs.py +65 -0
  1349. scipy/special/tests/test_ndtr.py +77 -0
  1350. scipy/special/tests/test_ndtri_exp.py +94 -0
  1351. scipy/special/tests/test_orthogonal.py +821 -0
  1352. scipy/special/tests/test_orthogonal_eval.py +275 -0
  1353. scipy/special/tests/test_owens_t.py +53 -0
  1354. scipy/special/tests/test_pcf.py +24 -0
  1355. scipy/special/tests/test_pdtr.py +48 -0
  1356. scipy/special/tests/test_powm1.py +65 -0
  1357. scipy/special/tests/test_precompute_expn_asy.py +24 -0
  1358. scipy/special/tests/test_precompute_gammainc.py +108 -0
  1359. scipy/special/tests/test_precompute_utils.py +36 -0
  1360. scipy/special/tests/test_round.py +18 -0
  1361. scipy/special/tests/test_sf_error.py +146 -0
  1362. scipy/special/tests/test_sici.py +36 -0
  1363. scipy/special/tests/test_specfun.py +48 -0
  1364. scipy/special/tests/test_spence.py +32 -0
  1365. scipy/special/tests/test_spfun_stats.py +61 -0
  1366. scipy/special/tests/test_sph_harm.py +85 -0
  1367. scipy/special/tests/test_spherical_bessel.py +400 -0
  1368. scipy/special/tests/test_support_alternative_backends.py +248 -0
  1369. scipy/special/tests/test_trig.py +72 -0
  1370. scipy/special/tests/test_ufunc_signatures.py +46 -0
  1371. scipy/special/tests/test_wright_bessel.py +205 -0
  1372. scipy/special/tests/test_wrightomega.py +117 -0
  1373. scipy/special/tests/test_zeta.py +301 -0
  1374. scipy/stats/__init__.py +670 -0
  1375. scipy/stats/_ansari_swilk_statistics.cp311-win_arm64.lib +0 -0
  1376. scipy/stats/_ansari_swilk_statistics.cp311-win_arm64.pyd +0 -0
  1377. scipy/stats/_axis_nan_policy.py +692 -0
  1378. scipy/stats/_biasedurn.cp311-win_arm64.lib +0 -0
  1379. scipy/stats/_biasedurn.cp311-win_arm64.pyd +0 -0
  1380. scipy/stats/_biasedurn.pxd +27 -0
  1381. scipy/stats/_binned_statistic.py +795 -0
  1382. scipy/stats/_binomtest.py +375 -0
  1383. scipy/stats/_bws_test.py +177 -0
  1384. scipy/stats/_censored_data.py +459 -0
  1385. scipy/stats/_common.py +5 -0
  1386. scipy/stats/_constants.py +42 -0
  1387. scipy/stats/_continued_fraction.py +387 -0
  1388. scipy/stats/_continuous_distns.py +12486 -0
  1389. scipy/stats/_correlation.py +210 -0
  1390. scipy/stats/_covariance.py +636 -0
  1391. scipy/stats/_crosstab.py +204 -0
  1392. scipy/stats/_discrete_distns.py +2098 -0
  1393. scipy/stats/_distn_infrastructure.py +4201 -0
  1394. scipy/stats/_distr_params.py +299 -0
  1395. scipy/stats/_distribution_infrastructure.py +5750 -0
  1396. scipy/stats/_entropy.py +428 -0
  1397. scipy/stats/_finite_differences.py +145 -0
  1398. scipy/stats/_fit.py +1351 -0
  1399. scipy/stats/_hypotests.py +2060 -0
  1400. scipy/stats/_kde.py +732 -0
  1401. scipy/stats/_ksstats.py +600 -0
  1402. scipy/stats/_levy_stable/__init__.py +1231 -0
  1403. scipy/stats/_levy_stable/levyst.cp311-win_arm64.lib +0 -0
  1404. scipy/stats/_levy_stable/levyst.cp311-win_arm64.pyd +0 -0
  1405. scipy/stats/_mannwhitneyu.py +492 -0
  1406. scipy/stats/_mgc.py +550 -0
  1407. scipy/stats/_morestats.py +4626 -0
  1408. scipy/stats/_mstats_basic.py +3658 -0
  1409. scipy/stats/_mstats_extras.py +521 -0
  1410. scipy/stats/_multicomp.py +449 -0
  1411. scipy/stats/_multivariate.py +7281 -0
  1412. scipy/stats/_new_distributions.py +452 -0
  1413. scipy/stats/_odds_ratio.py +466 -0
  1414. scipy/stats/_page_trend_test.py +486 -0
  1415. scipy/stats/_probability_distribution.py +1964 -0
  1416. scipy/stats/_qmc.py +2956 -0
  1417. scipy/stats/_qmc_cy.cp311-win_arm64.lib +0 -0
  1418. scipy/stats/_qmc_cy.cp311-win_arm64.pyd +0 -0
  1419. scipy/stats/_qmc_cy.pyi +54 -0
  1420. scipy/stats/_qmvnt.py +454 -0
  1421. scipy/stats/_qmvnt_cy.cp311-win_arm64.lib +0 -0
  1422. scipy/stats/_qmvnt_cy.cp311-win_arm64.pyd +0 -0
  1423. scipy/stats/_quantile.py +335 -0
  1424. scipy/stats/_rcont/__init__.py +4 -0
  1425. scipy/stats/_rcont/rcont.cp311-win_arm64.lib +0 -0
  1426. scipy/stats/_rcont/rcont.cp311-win_arm64.pyd +0 -0
  1427. scipy/stats/_relative_risk.py +263 -0
  1428. scipy/stats/_resampling.py +2352 -0
  1429. scipy/stats/_result_classes.py +40 -0
  1430. scipy/stats/_sampling.py +1314 -0
  1431. scipy/stats/_sensitivity_analysis.py +713 -0
  1432. scipy/stats/_sobol.cp311-win_arm64.lib +0 -0
  1433. scipy/stats/_sobol.cp311-win_arm64.pyd +0 -0
  1434. scipy/stats/_sobol.pyi +54 -0
  1435. scipy/stats/_sobol_direction_numbers.npz +0 -0
  1436. scipy/stats/_stats.cp311-win_arm64.lib +0 -0
  1437. scipy/stats/_stats.cp311-win_arm64.pyd +0 -0
  1438. scipy/stats/_stats.pxd +10 -0
  1439. scipy/stats/_stats_mstats_common.py +322 -0
  1440. scipy/stats/_stats_py.py +11089 -0
  1441. scipy/stats/_stats_pythran.cp311-win_arm64.lib +0 -0
  1442. scipy/stats/_stats_pythran.cp311-win_arm64.pyd +0 -0
  1443. scipy/stats/_survival.py +683 -0
  1444. scipy/stats/_tukeylambda_stats.py +199 -0
  1445. scipy/stats/_unuran/__init__.py +0 -0
  1446. scipy/stats/_unuran/unuran_wrapper.cp311-win_arm64.lib +0 -0
  1447. scipy/stats/_unuran/unuran_wrapper.cp311-win_arm64.pyd +0 -0
  1448. scipy/stats/_unuran/unuran_wrapper.pyi +179 -0
  1449. scipy/stats/_variation.py +126 -0
  1450. scipy/stats/_warnings_errors.py +38 -0
  1451. scipy/stats/_wilcoxon.py +265 -0
  1452. scipy/stats/biasedurn.py +16 -0
  1453. scipy/stats/contingency.py +521 -0
  1454. scipy/stats/distributions.py +24 -0
  1455. scipy/stats/kde.py +18 -0
  1456. scipy/stats/morestats.py +27 -0
  1457. scipy/stats/mstats.py +140 -0
  1458. scipy/stats/mstats_basic.py +42 -0
  1459. scipy/stats/mstats_extras.py +25 -0
  1460. scipy/stats/mvn.py +17 -0
  1461. scipy/stats/qmc.py +236 -0
  1462. scipy/stats/sampling.py +73 -0
  1463. scipy/stats/stats.py +41 -0
  1464. scipy/stats/tests/__init__.py +0 -0
  1465. scipy/stats/tests/common_tests.py +356 -0
  1466. scipy/stats/tests/data/_mvt.py +171 -0
  1467. scipy/stats/tests/data/fisher_exact_results_from_r.py +607 -0
  1468. scipy/stats/tests/data/jf_skew_t_gamlss_pdf_data.npy +0 -0
  1469. scipy/stats/tests/data/levy_stable/stable-Z1-cdf-sample-data.npy +0 -0
  1470. scipy/stats/tests/data/levy_stable/stable-Z1-pdf-sample-data.npy +0 -0
  1471. scipy/stats/tests/data/levy_stable/stable-loc-scale-sample-data.npy +0 -0
  1472. scipy/stats/tests/data/nist_anova/AtmWtAg.dat +108 -0
  1473. scipy/stats/tests/data/nist_anova/SiRstv.dat +85 -0
  1474. scipy/stats/tests/data/nist_anova/SmLs01.dat +249 -0
  1475. scipy/stats/tests/data/nist_anova/SmLs02.dat +1869 -0
  1476. scipy/stats/tests/data/nist_anova/SmLs03.dat +18069 -0
  1477. scipy/stats/tests/data/nist_anova/SmLs04.dat +249 -0
  1478. scipy/stats/tests/data/nist_anova/SmLs05.dat +1869 -0
  1479. scipy/stats/tests/data/nist_anova/SmLs06.dat +18069 -0
  1480. scipy/stats/tests/data/nist_anova/SmLs07.dat +249 -0
  1481. scipy/stats/tests/data/nist_anova/SmLs08.dat +1869 -0
  1482. scipy/stats/tests/data/nist_anova/SmLs09.dat +18069 -0
  1483. scipy/stats/tests/data/nist_linregress/Norris.dat +97 -0
  1484. scipy/stats/tests/data/rel_breitwigner_pdf_sample_data_ROOT.npy +0 -0
  1485. scipy/stats/tests/data/studentized_range_mpmath_ref.json +1499 -0
  1486. scipy/stats/tests/test_axis_nan_policy.py +1388 -0
  1487. scipy/stats/tests/test_binned_statistic.py +568 -0
  1488. scipy/stats/tests/test_censored_data.py +152 -0
  1489. scipy/stats/tests/test_contingency.py +294 -0
  1490. scipy/stats/tests/test_continued_fraction.py +173 -0
  1491. scipy/stats/tests/test_continuous.py +2198 -0
  1492. scipy/stats/tests/test_continuous_basic.py +1053 -0
  1493. scipy/stats/tests/test_continuous_fit_censored.py +683 -0
  1494. scipy/stats/tests/test_correlation.py +80 -0
  1495. scipy/stats/tests/test_crosstab.py +115 -0
  1496. scipy/stats/tests/test_discrete_basic.py +580 -0
  1497. scipy/stats/tests/test_discrete_distns.py +700 -0
  1498. scipy/stats/tests/test_distributions.py +10413 -0
  1499. scipy/stats/tests/test_entropy.py +322 -0
  1500. scipy/stats/tests/test_fast_gen_inversion.py +435 -0
  1501. scipy/stats/tests/test_fit.py +1090 -0
  1502. scipy/stats/tests/test_hypotests.py +1991 -0
  1503. scipy/stats/tests/test_kdeoth.py +676 -0
  1504. scipy/stats/tests/test_marray.py +289 -0
  1505. scipy/stats/tests/test_mgc.py +217 -0
  1506. scipy/stats/tests/test_morestats.py +3259 -0
  1507. scipy/stats/tests/test_mstats_basic.py +2071 -0
  1508. scipy/stats/tests/test_mstats_extras.py +172 -0
  1509. scipy/stats/tests/test_multicomp.py +405 -0
  1510. scipy/stats/tests/test_multivariate.py +4381 -0
  1511. scipy/stats/tests/test_odds_ratio.py +148 -0
  1512. scipy/stats/tests/test_qmc.py +1492 -0
  1513. scipy/stats/tests/test_quantile.py +199 -0
  1514. scipy/stats/tests/test_rank.py +345 -0
  1515. scipy/stats/tests/test_relative_risk.py +95 -0
  1516. scipy/stats/tests/test_resampling.py +2000 -0
  1517. scipy/stats/tests/test_sampling.py +1450 -0
  1518. scipy/stats/tests/test_sensitivity_analysis.py +310 -0
  1519. scipy/stats/tests/test_stats.py +9707 -0
  1520. scipy/stats/tests/test_survival.py +466 -0
  1521. scipy/stats/tests/test_tukeylambda_stats.py +85 -0
  1522. scipy/stats/tests/test_variation.py +216 -0
  1523. scipy/version.py +12 -0
  1524. scipy-1.16.2.dist-info/DELVEWHEEL +2 -0
  1525. scipy-1.16.2.dist-info/LICENSE.txt +912 -0
  1526. scipy-1.16.2.dist-info/METADATA +1061 -0
  1527. scipy-1.16.2.dist-info/RECORD +1530 -0
  1528. scipy-1.16.2.dist-info/WHEEL +4 -0
  1529. scipy.libs/msvcp140-5f1c5dd31916990d94181e07bc3afb32.dll +0 -0
  1530. scipy.libs/scipy_openblas-f3ac85b1f412f7e86514c923dc4058d1.dll +0 -0
@@ -0,0 +1,2469 @@
1
+ import operator
2
+ from math import prod
3
+
4
+ import numpy as np
5
+ from scipy._lib._util import normalize_axis_index
6
+ from scipy.linalg import (get_lapack_funcs, LinAlgError,
7
+ cholesky_banded, cho_solve_banded,
8
+ solve, solve_banded)
9
+ from scipy.optimize import minimize_scalar
10
+ from . import _dierckx
11
+ from . import _fitpack_impl
12
+ from scipy.sparse import csr_array
13
+ from scipy.special import poch
14
+ from itertools import combinations
15
+
16
+
17
+ __all__ = ["BSpline", "make_interp_spline", "make_lsq_spline",
18
+ "make_smoothing_spline"]
19
+
20
+
21
+ def _get_dtype(dtype):
22
+ """Return np.complex128 for complex dtypes, np.float64 otherwise."""
23
+ if np.issubdtype(dtype, np.complexfloating):
24
+ return np.complex128
25
+ else:
26
+ return np.float64
27
+
28
+
29
+ def _as_float_array(x, check_finite=False):
30
+ """Convert the input into a C contiguous float array.
31
+
32
+ NB: Upcasts half- and single-precision floats to double precision.
33
+ """
34
+ x = np.ascontiguousarray(x)
35
+ dtyp = _get_dtype(x.dtype)
36
+ x = x.astype(dtyp, copy=False)
37
+ if check_finite and not np.isfinite(x).all():
38
+ raise ValueError("Array must not contain infs or nans.")
39
+ return x
40
+
41
+
42
+ def _dual_poly(j, k, t, y):
43
+ """
44
+ Dual polynomial of the B-spline B_{j,k,t} -
45
+ polynomial which is associated with B_{j,k,t}:
46
+ $p_{j,k}(y) = (y - t_{j+1})(y - t_{j+2})...(y - t_{j+k})$
47
+ """
48
+ if k == 0:
49
+ return 1
50
+ return np.prod([(y - t[j + i]) for i in range(1, k + 1)])
51
+
52
+
53
+ def _diff_dual_poly(j, k, y, d, t):
54
+ """
55
+ d-th derivative of the dual polynomial $p_{j,k}(y)$
56
+ """
57
+ if d == 0:
58
+ return _dual_poly(j, k, t, y)
59
+ if d == k:
60
+ return poch(1, k)
61
+ comb = list(combinations(range(j + 1, j + k + 1), d))
62
+ res = 0
63
+ for i in range(len(comb) * len(comb[0])):
64
+ res += np.prod([(y - t[j + p]) for p in range(1, k + 1)
65
+ if (j + p) not in comb[i//d]])
66
+ return res
67
+
68
+
69
+ class BSpline:
70
+ r"""Univariate spline in the B-spline basis.
71
+
72
+ .. math::
73
+
74
+ S(x) = \sum_{j=0}^{n-1} c_j B_{j, k; t}(x)
75
+
76
+ where :math:`B_{j, k; t}` are B-spline basis functions of degree `k`
77
+ and knots `t`.
78
+
79
+ Parameters
80
+ ----------
81
+ t : ndarray, shape (n+k+1,)
82
+ knots
83
+ c : ndarray, shape (>=n, ...)
84
+ spline coefficients
85
+ k : int
86
+ B-spline degree
87
+ extrapolate : bool or 'periodic', optional
88
+ whether to extrapolate beyond the base interval, ``t[k] .. t[n]``,
89
+ or to return nans.
90
+ If True, extrapolates the first and last polynomial pieces of b-spline
91
+ functions active on the base interval.
92
+ If 'periodic', periodic extrapolation is used.
93
+ Default is True.
94
+ axis : int, optional
95
+ Interpolation axis. Default is zero.
96
+
97
+ Attributes
98
+ ----------
99
+ t : ndarray
100
+ knot vector
101
+ c : ndarray
102
+ spline coefficients
103
+ k : int
104
+ spline degree
105
+ extrapolate : bool
106
+ If True, extrapolates the first and last polynomial pieces of b-spline
107
+ functions active on the base interval.
108
+ axis : int
109
+ Interpolation axis.
110
+ tck : tuple
111
+ A read-only equivalent of ``(self.t, self.c, self.k)``
112
+
113
+ Methods
114
+ -------
115
+ __call__
116
+ basis_element
117
+ derivative
118
+ antiderivative
119
+ integrate
120
+ insert_knot
121
+ construct_fast
122
+ design_matrix
123
+ from_power_basis
124
+
125
+ Notes
126
+ -----
127
+ B-spline basis elements are defined via
128
+
129
+ .. math::
130
+
131
+ B_{i, 0}(x) = 1, \textrm{if $t_i \le x < t_{i+1}$, otherwise $0$,}
132
+
133
+ B_{i, k}(x) = \frac{x - t_i}{t_{i+k} - t_i} B_{i, k-1}(x)
134
+ + \frac{t_{i+k+1} - x}{t_{i+k+1} - t_{i+1}} B_{i+1, k-1}(x)
135
+
136
+ **Implementation details**
137
+
138
+ - At least ``k+1`` coefficients are required for a spline of degree `k`,
139
+ so that ``n >= k+1``. Additional coefficients, ``c[j]`` with
140
+ ``j > n``, are ignored.
141
+
142
+ - B-spline basis elements of degree `k` form a partition of unity on the
143
+ *base interval*, ``t[k] <= x <= t[n]``.
144
+
145
+
146
+ Examples
147
+ --------
148
+
149
+ Translating the recursive definition of B-splines into Python code, we have:
150
+
151
+ >>> def B(x, k, i, t):
152
+ ... if k == 0:
153
+ ... return 1.0 if t[i] <= x < t[i+1] else 0.0
154
+ ... if t[i+k] == t[i]:
155
+ ... c1 = 0.0
156
+ ... else:
157
+ ... c1 = (x - t[i])/(t[i+k] - t[i]) * B(x, k-1, i, t)
158
+ ... if t[i+k+1] == t[i+1]:
159
+ ... c2 = 0.0
160
+ ... else:
161
+ ... c2 = (t[i+k+1] - x)/(t[i+k+1] - t[i+1]) * B(x, k-1, i+1, t)
162
+ ... return c1 + c2
163
+
164
+ >>> def bspline(x, t, c, k):
165
+ ... n = len(t) - k - 1
166
+ ... assert (n >= k+1) and (len(c) >= n)
167
+ ... return sum(c[i] * B(x, k, i, t) for i in range(n))
168
+
169
+ Note that this is an inefficient (if straightforward) way to
170
+ evaluate B-splines --- this spline class does it in an equivalent,
171
+ but much more efficient way.
172
+
173
+ Here we construct a quadratic spline function on the base interval
174
+ ``2 <= x <= 4`` and compare with the naive way of evaluating the spline:
175
+
176
+ >>> from scipy.interpolate import BSpline
177
+ >>> k = 2
178
+ >>> t = [0, 1, 2, 3, 4, 5, 6]
179
+ >>> c = [-1, 2, 0, -1]
180
+ >>> spl = BSpline(t, c, k)
181
+ >>> spl(2.5)
182
+ array(1.375)
183
+ >>> bspline(2.5, t, c, k)
184
+ 1.375
185
+
186
+ Note that outside of the base interval results differ. This is because
187
+ `BSpline` extrapolates the first and last polynomial pieces of B-spline
188
+ functions active on the base interval.
189
+
190
+ >>> import matplotlib.pyplot as plt
191
+ >>> import numpy as np
192
+ >>> fig, ax = plt.subplots()
193
+ >>> xx = np.linspace(1.5, 4.5, 50)
194
+ >>> ax.plot(xx, [bspline(x, t, c ,k) for x in xx], 'r-', lw=3, label='naive')
195
+ >>> ax.plot(xx, spl(xx), 'b-', lw=4, alpha=0.7, label='BSpline')
196
+ >>> ax.grid(True)
197
+ >>> ax.legend(loc='best')
198
+ >>> plt.show()
199
+
200
+
201
+ References
202
+ ----------
203
+ .. [1] Tom Lyche and Knut Morken, Spline methods,
204
+ http://www.uio.no/studier/emner/matnat/ifi/INF-MAT5340/v05/undervisningsmateriale/
205
+ .. [2] Carl de Boor, A practical guide to splines, Springer, 2001.
206
+
207
+ """
208
+
209
+ def __init__(self, t, c, k, extrapolate=True, axis=0):
210
+ super().__init__()
211
+
212
+ self.k = operator.index(k)
213
+ self.c = np.asarray(c)
214
+ self.t = np.ascontiguousarray(t, dtype=np.float64)
215
+
216
+ if extrapolate == 'periodic':
217
+ self.extrapolate = extrapolate
218
+ else:
219
+ self.extrapolate = bool(extrapolate)
220
+
221
+ n = self.t.shape[0] - self.k - 1
222
+
223
+ axis = normalize_axis_index(axis, self.c.ndim)
224
+
225
+ # Note that the normalized axis is stored in the object.
226
+ self.axis = axis
227
+ if axis != 0:
228
+ # roll the interpolation axis to be the first one in self.c
229
+ # More specifically, the target shape for self.c is (n, ...),
230
+ # and axis !=0 means that we have c.shape (..., n, ...)
231
+ # ^
232
+ # axis
233
+ self.c = np.moveaxis(self.c, axis, 0)
234
+
235
+ if k < 0:
236
+ raise ValueError("Spline order cannot be negative.")
237
+ if self.t.ndim != 1:
238
+ raise ValueError("Knot vector must be one-dimensional.")
239
+ if n < self.k + 1:
240
+ raise ValueError(f"Need at least {2*k + 2} knots for degree {k}")
241
+ if (np.diff(self.t) < 0).any():
242
+ raise ValueError("Knots must be in a non-decreasing order.")
243
+ if len(np.unique(self.t[k:n+1])) < 2:
244
+ raise ValueError("Need at least two internal knots.")
245
+ if not np.isfinite(self.t).all():
246
+ raise ValueError("Knots should not have nans or infs.")
247
+ if self.c.ndim < 1:
248
+ raise ValueError("Coefficients must be at least 1-dimensional.")
249
+ if self.c.shape[0] < n:
250
+ raise ValueError("Knots, coefficients and degree are inconsistent.")
251
+
252
+ dt = _get_dtype(self.c.dtype)
253
+ self.c = np.ascontiguousarray(self.c, dtype=dt)
254
+
255
+ @classmethod
256
+ def construct_fast(cls, t, c, k, extrapolate=True, axis=0):
257
+ """Construct a spline without making checks.
258
+
259
+ Accepts same parameters as the regular constructor. Input arrays
260
+ `t` and `c` must of correct shape and dtype.
261
+ """
262
+ self = object.__new__(cls)
263
+ self.t, self.c, self.k = t, c, k
264
+ self.extrapolate = extrapolate
265
+ self.axis = axis
266
+ return self
267
+
268
+ @property
269
+ def tck(self):
270
+ """Equivalent to ``(self.t, self.c, self.k)`` (read-only).
271
+ """
272
+ return self.t, self.c, self.k
273
+
274
+ @classmethod
275
+ def basis_element(cls, t, extrapolate=True):
276
+ """Return a B-spline basis element ``B(x | t[0], ..., t[k+1])``.
277
+
278
+ Parameters
279
+ ----------
280
+ t : ndarray, shape (k+2,)
281
+ internal knots
282
+ extrapolate : bool or 'periodic', optional
283
+ whether to extrapolate beyond the base interval, ``t[0] .. t[k+1]``,
284
+ or to return nans.
285
+ If 'periodic', periodic extrapolation is used.
286
+ Default is True.
287
+
288
+ Returns
289
+ -------
290
+ basis_element : callable
291
+ A callable representing a B-spline basis element for the knot
292
+ vector `t`.
293
+
294
+ Notes
295
+ -----
296
+ The degree of the B-spline, `k`, is inferred from the length of `t` as
297
+ ``len(t)-2``. The knot vector is constructed by appending and prepending
298
+ ``k+1`` elements to internal knots `t`.
299
+
300
+ Examples
301
+ --------
302
+
303
+ Construct a cubic B-spline:
304
+
305
+ >>> import numpy as np
306
+ >>> from scipy.interpolate import BSpline
307
+ >>> b = BSpline.basis_element([0, 1, 2, 3, 4])
308
+ >>> k = b.k
309
+ >>> b.t[k:-k]
310
+ array([ 0., 1., 2., 3., 4.])
311
+ >>> k
312
+ 3
313
+
314
+ Construct a quadratic B-spline on ``[0, 1, 1, 2]``, and compare
315
+ to its explicit form:
316
+
317
+ >>> t = [0, 1, 1, 2]
318
+ >>> b = BSpline.basis_element(t)
319
+ >>> def f(x):
320
+ ... return np.where(x < 1, x*x, (2. - x)**2)
321
+
322
+ >>> import matplotlib.pyplot as plt
323
+ >>> fig, ax = plt.subplots()
324
+ >>> x = np.linspace(0, 2, 51)
325
+ >>> ax.plot(x, b(x), 'g', lw=3)
326
+ >>> ax.plot(x, f(x), 'r', lw=8, alpha=0.4)
327
+ >>> ax.grid(True)
328
+ >>> plt.show()
329
+
330
+ """
331
+ k = len(t) - 2
332
+ t = _as_float_array(t)
333
+ t = np.r_[(t[0]-1,) * k, t, (t[-1]+1,) * k]
334
+ c = np.zeros_like(t)
335
+ c[k] = 1.
336
+ return cls.construct_fast(t, c, k, extrapolate)
337
+
338
+ @classmethod
339
+ def design_matrix(cls, x, t, k, extrapolate=False):
340
+ """
341
+ Returns a design matrix as a CSR format sparse array.
342
+
343
+ Parameters
344
+ ----------
345
+ x : array_like, shape (n,)
346
+ Points to evaluate the spline at.
347
+ t : array_like, shape (nt,)
348
+ Sorted 1D array of knots.
349
+ k : int
350
+ B-spline degree.
351
+ extrapolate : bool or 'periodic', optional
352
+ Whether to extrapolate based on the first and last intervals
353
+ or raise an error. If 'periodic', periodic extrapolation is used.
354
+ Default is False.
355
+
356
+ .. versionadded:: 1.10.0
357
+
358
+ Returns
359
+ -------
360
+ design_matrix : `csr_array` object
361
+ Sparse matrix in CSR format where each row contains all the basis
362
+ elements of the input row (first row = basis elements of x[0],
363
+ ..., last row = basis elements x[-1]).
364
+
365
+ Examples
366
+ --------
367
+ Construct a design matrix for a B-spline
368
+
369
+ >>> from scipy.interpolate import make_interp_spline, BSpline
370
+ >>> import numpy as np
371
+ >>> x = np.linspace(0, np.pi * 2, 4)
372
+ >>> y = np.sin(x)
373
+ >>> k = 3
374
+ >>> bspl = make_interp_spline(x, y, k=k)
375
+ >>> design_matrix = bspl.design_matrix(x, bspl.t, k)
376
+ >>> design_matrix.toarray()
377
+ [[1. , 0. , 0. , 0. ],
378
+ [0.2962963 , 0.44444444, 0.22222222, 0.03703704],
379
+ [0.03703704, 0.22222222, 0.44444444, 0.2962963 ],
380
+ [0. , 0. , 0. , 1. ]]
381
+
382
+ Construct a design matrix for some vector of knots
383
+
384
+ >>> k = 2
385
+ >>> t = [-1, 0, 1, 2, 3, 4, 5, 6]
386
+ >>> x = [1, 2, 3, 4]
387
+ >>> design_matrix = BSpline.design_matrix(x, t, k).toarray()
388
+ >>> design_matrix
389
+ [[0.5, 0.5, 0. , 0. , 0. ],
390
+ [0. , 0.5, 0.5, 0. , 0. ],
391
+ [0. , 0. , 0.5, 0.5, 0. ],
392
+ [0. , 0. , 0. , 0.5, 0.5]]
393
+
394
+ This result is equivalent to the one created in the sparse format
395
+
396
+ >>> c = np.eye(len(t) - k - 1)
397
+ >>> design_matrix_gh = BSpline(t, c, k)(x)
398
+ >>> np.allclose(design_matrix, design_matrix_gh, atol=1e-14)
399
+ True
400
+
401
+ Notes
402
+ -----
403
+ .. versionadded:: 1.8.0
404
+
405
+ In each row of the design matrix all the basis elements are evaluated
406
+ at the certain point (first row - x[0], ..., last row - x[-1]).
407
+
408
+ `nt` is a length of the vector of knots: as far as there are
409
+ `nt - k - 1` basis elements, `nt` should be not less than `2 * k + 2`
410
+ to have at least `k + 1` basis element.
411
+
412
+ Out of bounds `x` raises a ValueError.
413
+ """
414
+ x = _as_float_array(x, True)
415
+ t = _as_float_array(t, True)
416
+
417
+ if extrapolate != 'periodic':
418
+ extrapolate = bool(extrapolate)
419
+
420
+ if k < 0:
421
+ raise ValueError("Spline order cannot be negative.")
422
+ if t.ndim != 1 or np.any(t[1:] < t[:-1]):
423
+ raise ValueError(f"Expect t to be a 1-D sorted array_like, but "
424
+ f"got t={t}.")
425
+ # There are `nt - k - 1` basis elements in a BSpline built on the
426
+ # vector of knots with length `nt`, so to have at least `k + 1` basis
427
+ # elements we need to have at least `2 * k + 2` elements in the vector
428
+ # of knots.
429
+ if len(t) < 2 * k + 2:
430
+ raise ValueError(f"Length t is not enough for k={k}.")
431
+
432
+ if extrapolate == 'periodic':
433
+ # With periodic extrapolation we map x to the segment
434
+ # [t[k], t[n]].
435
+ n = t.size - k - 1
436
+ x = t[k] + (x - t[k]) % (t[n] - t[k])
437
+ extrapolate = False
438
+ elif not extrapolate and (
439
+ (min(x) < t[k]) or (max(x) > t[t.shape[0] - k - 1])
440
+ ):
441
+ # Checks from `find_interval` function
442
+ raise ValueError(f'Out of bounds w/ x = {x}.')
443
+
444
+ # Compute number of non-zeros of final CSR array in order to determine
445
+ # the dtype of indices and indptr of the CSR array.
446
+ n = x.shape[0]
447
+ nnz = n * (k + 1)
448
+ if nnz < np.iinfo(np.int32).max:
449
+ int_dtype = np.int32
450
+ else:
451
+ int_dtype = np.int64
452
+
453
+ # Get the non-zero elements of the design matrix and per-row `offsets`:
454
+ # In row `i`, k+1 nonzero elements are consecutive, and start from `offset[i]`
455
+ data, offsets, _ = _dierckx.data_matrix(x, t, k, np.ones_like(x), extrapolate)
456
+ data = data.ravel()
457
+
458
+ if offsets.dtype != int_dtype:
459
+ offsets = offsets.astype(int_dtype)
460
+
461
+ # Convert from per-row offsets to the CSR indices/indptr format
462
+ indices = np.repeat(offsets, k+1).reshape(-1, k+1)
463
+ indices = indices + np.arange(k+1, dtype=int_dtype)
464
+ indices = indices.ravel()
465
+
466
+ indptr = np.arange(0, (n + 1) * (k + 1), k + 1, dtype=int_dtype)
467
+
468
+ return csr_array(
469
+ (data, indices, indptr),
470
+ shape=(x.shape[0], t.shape[0] - k - 1)
471
+ )
472
+
473
+ def __call__(self, x, nu=0, extrapolate=None):
474
+ """
475
+ Evaluate a spline function.
476
+
477
+ Parameters
478
+ ----------
479
+ x : array_like
480
+ points to evaluate the spline at.
481
+ nu : int, optional
482
+ derivative to evaluate (default is 0).
483
+ extrapolate : bool or 'periodic', optional
484
+ whether to extrapolate based on the first and last intervals
485
+ or return nans. If 'periodic', periodic extrapolation is used.
486
+ Default is `self.extrapolate`.
487
+
488
+ Returns
489
+ -------
490
+ y : array_like
491
+ Shape is determined by replacing the interpolation axis
492
+ in the coefficient array with the shape of `x`.
493
+
494
+ """
495
+ if extrapolate is None:
496
+ extrapolate = self.extrapolate
497
+ x = np.asarray(x)
498
+ x_shape, x_ndim = x.shape, x.ndim
499
+ x = np.ascontiguousarray(x.ravel(), dtype=np.float64)
500
+
501
+ # With periodic extrapolation we map x to the segment
502
+ # [self.t[k], self.t[n]].
503
+ if extrapolate == 'periodic':
504
+ n = self.t.size - self.k - 1
505
+ x = self.t[self.k] + (x - self.t[self.k]) % (self.t[n] - self.t[self.k])
506
+ extrapolate = False
507
+
508
+ self._ensure_c_contiguous()
509
+
510
+ # if self.c is complex: the C code in _dierckxmodule.cc expects
511
+ # floats, so make a view---this expands the last axis, and
512
+ # the view is C contiguous if the original is.
513
+ # if c.dtype is complex of shape (n,), c.view(float).shape == (2*n,)
514
+ # if c.dtype is complex of shape (n, m), c.view(float).shape == (n, 2*m)
515
+
516
+ is_complex = self.c.dtype.kind == 'c'
517
+ if is_complex:
518
+ cc = self.c.view(float)
519
+ if self.c.ndim == 1:
520
+ cc = cc.reshape(self.c.shape[0], 2)
521
+ else:
522
+ cc = self.c
523
+
524
+ # flatten the trailing dims
525
+ cc = cc.reshape(cc.shape[0], -1)
526
+
527
+ # heavy lifting: actually perform the evaluations
528
+ out = _dierckx.evaluate_spline(self.t, cc, self.k, x, nu, extrapolate)
529
+
530
+ if is_complex:
531
+ out = out.view(complex)
532
+
533
+ out = out.reshape(x_shape + self.c.shape[1:])
534
+ if self.axis != 0:
535
+ # transpose to move the calculated values to the interpolation axis
536
+ l = list(range(out.ndim))
537
+ l = l[x_ndim:x_ndim+self.axis] + l[:x_ndim] + l[x_ndim+self.axis:]
538
+ out = out.transpose(l)
539
+ return out
540
+
541
+ def _ensure_c_contiguous(self):
542
+ """
543
+ c and t may be modified by the user. The Cython code expects
544
+ that they are C contiguous.
545
+
546
+ """
547
+ if not self.t.flags.c_contiguous:
548
+ self.t = self.t.copy()
549
+ if not self.c.flags.c_contiguous:
550
+ self.c = self.c.copy()
551
+
552
+ def derivative(self, nu=1):
553
+ """Return a B-spline representing the derivative.
554
+
555
+ Parameters
556
+ ----------
557
+ nu : int, optional
558
+ Derivative order.
559
+ Default is 1.
560
+
561
+ Returns
562
+ -------
563
+ b : `BSpline` object
564
+ A new instance representing the derivative.
565
+
566
+ See Also
567
+ --------
568
+ splder, splantider
569
+
570
+ """
571
+ c = self.c.copy()
572
+ # pad the c array if needed
573
+ ct = len(self.t) - len(c)
574
+ if ct > 0:
575
+ c = np.r_[c, np.zeros((ct,) + c.shape[1:])]
576
+ tck = _fitpack_impl.splder((self.t, c, self.k), nu)
577
+ return self.construct_fast(*tck, extrapolate=self.extrapolate,
578
+ axis=self.axis)
579
+
580
+ def antiderivative(self, nu=1):
581
+ """Return a B-spline representing the antiderivative.
582
+
583
+ Parameters
584
+ ----------
585
+ nu : int, optional
586
+ Antiderivative order. Default is 1.
587
+
588
+ Returns
589
+ -------
590
+ b : `BSpline` object
591
+ A new instance representing the antiderivative.
592
+
593
+ Notes
594
+ -----
595
+ If antiderivative is computed and ``self.extrapolate='periodic'``,
596
+ it will be set to False for the returned instance. This is done because
597
+ the antiderivative is no longer periodic and its correct evaluation
598
+ outside of the initially given x interval is difficult.
599
+
600
+ See Also
601
+ --------
602
+ splder, splantider
603
+
604
+ """
605
+ c = self.c.copy()
606
+ # pad the c array if needed
607
+ ct = len(self.t) - len(c)
608
+ if ct > 0:
609
+ c = np.r_[c, np.zeros((ct,) + c.shape[1:])]
610
+ tck = _fitpack_impl.splantider((self.t, c, self.k), nu)
611
+
612
+ if self.extrapolate == 'periodic':
613
+ extrapolate = False
614
+ else:
615
+ extrapolate = self.extrapolate
616
+
617
+ return self.construct_fast(*tck, extrapolate=extrapolate,
618
+ axis=self.axis)
619
+
620
+ def integrate(self, a, b, extrapolate=None):
621
+ """Compute a definite integral of the spline.
622
+
623
+ Parameters
624
+ ----------
625
+ a : float
626
+ Lower limit of integration.
627
+ b : float
628
+ Upper limit of integration.
629
+ extrapolate : bool or 'periodic', optional
630
+ whether to extrapolate beyond the base interval,
631
+ ``t[k] .. t[-k-1]``, or take the spline to be zero outside of the
632
+ base interval. If 'periodic', periodic extrapolation is used.
633
+ If None (default), use `self.extrapolate`.
634
+
635
+ Returns
636
+ -------
637
+ I : array_like
638
+ Definite integral of the spline over the interval ``[a, b]``.
639
+
640
+ Examples
641
+ --------
642
+ Construct the linear spline ``x if x < 1 else 2 - x`` on the base
643
+ interval :math:`[0, 2]`, and integrate it
644
+
645
+ >>> from scipy.interpolate import BSpline
646
+ >>> b = BSpline.basis_element([0, 1, 2])
647
+ >>> b.integrate(0, 1)
648
+ array(0.5)
649
+
650
+ If the integration limits are outside of the base interval, the result
651
+ is controlled by the `extrapolate` parameter
652
+
653
+ >>> b.integrate(-1, 1)
654
+ array(0.0)
655
+ >>> b.integrate(-1, 1, extrapolate=False)
656
+ array(0.5)
657
+
658
+ >>> import matplotlib.pyplot as plt
659
+ >>> fig, ax = plt.subplots()
660
+ >>> ax.grid(True)
661
+ >>> ax.axvline(0, c='r', lw=5, alpha=0.5) # base interval
662
+ >>> ax.axvline(2, c='r', lw=5, alpha=0.5)
663
+ >>> xx = [-1, 1, 2]
664
+ >>> ax.plot(xx, b(xx))
665
+ >>> plt.show()
666
+
667
+ """
668
+ if extrapolate is None:
669
+ extrapolate = self.extrapolate
670
+
671
+ # Prepare self.t and self.c.
672
+ self._ensure_c_contiguous()
673
+
674
+ # Swap integration bounds if needed.
675
+ sign = 1
676
+ if b < a:
677
+ a, b = b, a
678
+ sign = -1
679
+ n = self.t.size - self.k - 1
680
+
681
+ if extrapolate != "periodic" and not extrapolate:
682
+ # Shrink the integration interval, if needed.
683
+ a = max(a, self.t[self.k])
684
+ b = min(b, self.t[n])
685
+
686
+ if self.c.ndim == 1:
687
+ # Fast path: use FITPACK's routine
688
+ # (cf _fitpack_impl.splint).
689
+ integral = _fitpack_impl.splint(a, b, self.tck)
690
+ return np.asarray(integral * sign)
691
+
692
+ # Compute the antiderivative.
693
+ c = self.c
694
+ ct = len(self.t) - len(c)
695
+ if ct > 0:
696
+ c = np.r_[c, np.zeros((ct,) + c.shape[1:])]
697
+ ta, ca, ka = _fitpack_impl.splantider((self.t, c, self.k), 1)
698
+
699
+ if extrapolate == 'periodic':
700
+ # Split the integral into the part over period (can be several
701
+ # of them) and the remaining part.
702
+
703
+ ts, te = self.t[self.k], self.t[n]
704
+ period = te - ts
705
+ interval = b - a
706
+ n_periods, left = divmod(interval, period)
707
+
708
+ if n_periods > 0:
709
+ # Evaluate the difference of antiderivatives.
710
+ x = np.asarray([ts, te], dtype=np.float64)
711
+ out = _dierckx.evaluate_spline(ta, ca.reshape(ca.shape[0], -1),
712
+ ka, x, 0, False)
713
+ integral = out[1] - out[0]
714
+ integral *= n_periods
715
+ else:
716
+ integral = np.zeros((1, prod(self.c.shape[1:])),
717
+ dtype=self.c.dtype)
718
+
719
+ # Map a to [ts, te], b is always a + left.
720
+ a = ts + (a - ts) % period
721
+ b = a + left
722
+
723
+ # If b <= te then we need to integrate over [a, b], otherwise
724
+ # over [a, te] and from xs to what is remained.
725
+ if b <= te:
726
+ x = np.asarray([a, b], dtype=np.float64)
727
+ out = _dierckx.evaluate_spline(ta, ca.reshape(ca.shape[0], -1),
728
+ ka, x, 0, False)
729
+ integral += out[1] - out[0]
730
+ else:
731
+ x = np.asarray([a, te], dtype=np.float64)
732
+ out = _dierckx.evaluate_spline(ta, ca.reshape(ca.shape[0], -1),
733
+ ka, x, 0, False)
734
+ integral += out[1] - out[0]
735
+
736
+ x = np.asarray([ts, ts + b - te], dtype=np.float64)
737
+ out = _dierckx.evaluate_spline(ta, ca.reshape(ca.shape[0], -1),
738
+ ka, x, 0, False)
739
+ integral += out[1] - out[0]
740
+ else:
741
+ # Evaluate the difference of antiderivatives.
742
+ x = np.asarray([a, b], dtype=np.float64)
743
+ out = _dierckx.evaluate_spline(ta, ca.reshape(ca.shape[0], -1),
744
+ ka, x, 0, extrapolate)
745
+ integral = out[1] - out[0]
746
+
747
+ integral *= sign
748
+ return integral.reshape(ca.shape[1:])
749
+
750
+ @classmethod
751
+ def from_power_basis(cls, pp, bc_type='not-a-knot'):
752
+ r"""
753
+ Construct a polynomial in the B-spline basis
754
+ from a piecewise polynomial in the power basis.
755
+
756
+ For now, accepts ``CubicSpline`` instances only.
757
+
758
+ Parameters
759
+ ----------
760
+ pp : CubicSpline
761
+ A piecewise polynomial in the power basis, as created
762
+ by ``CubicSpline``
763
+ bc_type : string, optional
764
+ Boundary condition type as in ``CubicSpline``: one of the
765
+ ``not-a-knot``, ``natural``, ``clamped``, or ``periodic``.
766
+ Necessary for construction an instance of ``BSpline`` class.
767
+ Default is ``not-a-knot``.
768
+
769
+ Returns
770
+ -------
771
+ b : `BSpline` object
772
+ A new instance representing the initial polynomial
773
+ in the B-spline basis.
774
+
775
+ Notes
776
+ -----
777
+ .. versionadded:: 1.8.0
778
+
779
+ Accepts only ``CubicSpline`` instances for now.
780
+
781
+ The algorithm follows from differentiation
782
+ the Marsden's identity [1]: each of coefficients of spline
783
+ interpolation function in the B-spline basis is computed as follows:
784
+
785
+ .. math::
786
+
787
+ c_j = \sum_{m=0}^{k} \frac{(k-m)!}{k!}
788
+ c_{m,i} (-1)^{k-m} D^m p_{j,k}(x_i)
789
+
790
+ :math:`c_{m, i}` - a coefficient of CubicSpline,
791
+ :math:`D^m p_{j, k}(x_i)` - an m-th defivative of a dual polynomial
792
+ in :math:`x_i`.
793
+
794
+ ``k`` always equals 3 for now.
795
+
796
+ First ``n - 2`` coefficients are computed in :math:`x_i = x_j`, e.g.
797
+
798
+ .. math::
799
+
800
+ c_1 = \sum_{m=0}^{k} \frac{(k-1)!}{k!} c_{m,1} D^m p_{j,3}(x_1)
801
+
802
+ Last ``nod + 2`` coefficients are computed in ``x[-2]``,
803
+ ``nod`` - number of derivatives at the ends.
804
+
805
+ For example, consider :math:`x = [0, 1, 2, 3, 4]`,
806
+ :math:`y = [1, 1, 1, 1, 1]` and bc_type = ``natural``
807
+
808
+ The coefficients of CubicSpline in the power basis:
809
+
810
+ :math:`[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0],
811
+ [0, 0, 0, 0, 0], [1, 1, 1, 1, 1]]`
812
+
813
+ The knot vector: :math:`t = [0, 0, 0, 0, 1, 2, 3, 4, 4, 4, 4]`
814
+
815
+ In this case
816
+
817
+ .. math::
818
+
819
+ c_j = \frac{0!}{k!} c_{3, i} k! = c_{3, i} = 1,~j = 0, ..., 6
820
+
821
+ References
822
+ ----------
823
+ .. [1] Tom Lyche and Knut Morken, Spline Methods, 2005, Section 3.1.2
824
+
825
+ """
826
+ from ._cubic import CubicSpline
827
+ if not isinstance(pp, CubicSpline):
828
+ raise NotImplementedError(f"Only CubicSpline objects are accepted "
829
+ f"for now. Got {type(pp)} instead.")
830
+ x = pp.x
831
+ coef = pp.c
832
+ k = pp.c.shape[0] - 1
833
+ n = x.shape[0]
834
+
835
+ if bc_type == 'not-a-knot':
836
+ t = _not_a_knot(x, k)
837
+ elif bc_type == 'natural' or bc_type == 'clamped':
838
+ t = _augknt(x, k)
839
+ elif bc_type == 'periodic':
840
+ t = _periodic_knots(x, k)
841
+ else:
842
+ raise TypeError(f'Unknown boundary condition: {bc_type}')
843
+
844
+ nod = t.shape[0] - (n + k + 1) # number of derivatives at the ends
845
+ c = np.zeros(n + nod, dtype=pp.c.dtype)
846
+ for m in range(k + 1):
847
+ for i in range(n - 2):
848
+ c[i] += poch(k + 1, -m) * coef[m, i]\
849
+ * np.power(-1, k - m)\
850
+ * _diff_dual_poly(i, k, x[i], m, t)
851
+ for j in range(n - 2, n + nod):
852
+ c[j] += poch(k + 1, -m) * coef[m, n - 2]\
853
+ * np.power(-1, k - m)\
854
+ * _diff_dual_poly(j, k, x[n - 2], m, t)
855
+ return cls.construct_fast(t, c, k, pp.extrapolate, pp.axis)
856
+
857
+ def insert_knot(self, x, m=1):
858
+ """Insert a new knot at `x` of multiplicity `m`.
859
+
860
+ Given the knots and coefficients of a B-spline representation, create a
861
+ new B-spline with a knot inserted `m` times at point `x`.
862
+
863
+ Parameters
864
+ ----------
865
+ x : float
866
+ The position of the new knot
867
+ m : int, optional
868
+ The number of times to insert the given knot (its multiplicity).
869
+ Default is 1.
870
+
871
+ Returns
872
+ -------
873
+ spl : `BSpline` object
874
+ A new `BSpline` object with the new knot inserted.
875
+
876
+ Notes
877
+ -----
878
+ Based on algorithms from [1]_ and [2]_.
879
+
880
+ In case of a periodic spline (``self.extrapolate == "periodic"``)
881
+ there must be either at least k interior knots t(j) satisfying
882
+ ``t(k+1)<t(j)<=x`` or at least k interior knots t(j) satisfying
883
+ ``x<=t(j)<t(n-k)``.
884
+
885
+ This routine is functionally equivalent to `scipy.interpolate.insert`.
886
+
887
+ .. versionadded:: 1.13
888
+
889
+ References
890
+ ----------
891
+ .. [1] W. Boehm, "Inserting new knots into b-spline curves.",
892
+ Computer Aided Design, 12, p.199-201, 1980.
893
+ :doi:`10.1016/0010-4485(80)90154-2`.
894
+ .. [2] P. Dierckx, "Curve and surface fitting with splines, Monographs on
895
+ Numerical Analysis", Oxford University Press, 1993.
896
+
897
+ See Also
898
+ --------
899
+ scipy.interpolate.insert
900
+
901
+ Examples
902
+ --------
903
+ You can insert knots into a B-spline:
904
+
905
+ >>> import numpy as np
906
+ >>> from scipy.interpolate import BSpline, make_interp_spline
907
+ >>> x = np.linspace(0, 10, 5)
908
+ >>> y = np.sin(x)
909
+ >>> spl = make_interp_spline(x, y, k=3)
910
+ >>> spl.t
911
+ array([ 0., 0., 0., 0., 5., 10., 10., 10., 10.])
912
+
913
+ Insert a single knot
914
+
915
+ >>> spl_1 = spl.insert_knot(3)
916
+ >>> spl_1.t
917
+ array([ 0., 0., 0., 0., 3., 5., 10., 10., 10., 10.])
918
+
919
+ Insert a multiple knot
920
+
921
+ >>> spl_2 = spl.insert_knot(8, m=3)
922
+ >>> spl_2.t
923
+ array([ 0., 0., 0., 0., 5., 8., 8., 8., 10., 10., 10., 10.])
924
+
925
+ """
926
+ if x < self.t[self.k] or x > self.t[-self.k-1]:
927
+ raise ValueError(f"Cannot insert a knot at {x}.")
928
+ if m <= 0:
929
+ raise ValueError(f"`m` must be positive, got {m = }.")
930
+
931
+ tt = self.t.copy()
932
+ cc = self.c.copy()
933
+
934
+ for _ in range(m):
935
+ tt, cc = _insert(x, tt, cc, self.k, self.extrapolate == "periodic")
936
+ return self.construct_fast(tt, cc, self.k, self.extrapolate, self.axis)
937
+
938
+
939
+ def _insert(xval, t, c, k, periodic=False):
940
+ """Insert a single knot at `xval`."""
941
+ #
942
+ # This is a port of the FORTRAN `insert` routine by P. Dierckx,
943
+ # https://github.com/scipy/scipy/blob/maintenance/1.11.x/scipy/interpolate/fitpack/insert.f
944
+ # which carries the following comment:
945
+ #
946
+ # subroutine insert inserts a new knot x into a spline function s(x)
947
+ # of degree k and calculates the b-spline representation of s(x) with
948
+ # respect to the new set of knots. in addition, if iopt.ne.0, s(x)
949
+ # will be considered as a periodic spline with period per=t(n-k)-t(k+1)
950
+ # satisfying the boundary constraints
951
+ # t(i+n-2*k-1) = t(i)+per ,i=1,2,...,2*k+1
952
+ # c(i+n-2*k-1) = c(i) ,i=1,2,...,k
953
+ # in that case, the knots and b-spline coefficients returned will also
954
+ # satisfy these boundary constraints, i.e.
955
+ # tt(i+nn-2*k-1) = tt(i)+per ,i=1,2,...,2*k+1
956
+ # cc(i+nn-2*k-1) = cc(i) ,i=1,2,...,k
957
+ interval = _dierckx.find_interval(t, k, float(xval), k, False)
958
+ if interval < 0:
959
+ # extrapolated values are guarded for in BSpline.insert_knot
960
+ raise ValueError(f"Cannot insert the knot at {xval}.")
961
+
962
+ # super edge case: a knot with multiplicity > k+1
963
+ # see https://github.com/scipy/scipy/commit/037204c3e91
964
+ if t[interval] == t[interval + k + 1]:
965
+ interval -= 1
966
+
967
+ if periodic:
968
+ if (interval + 1 <= 2*k) and (interval + 1 >= t.shape[0] - 2*k):
969
+ # in case of a periodic spline (iopt.ne.0) there must be
970
+ # either at least k interior knots t(j) satisfying t(k+1)<t(j)<=x
971
+ # or at least k interior knots t(j) satisfying x<=t(j)<t(n-k)
972
+ raise ValueError("Not enough internal knots.")
973
+
974
+ # knots
975
+ tt = np.r_[t[:interval+1], xval, t[interval+1:]]
976
+
977
+ newshape = (c.shape[0] + 1,) + c.shape[1:]
978
+ cc = np.zeros(newshape, dtype=c.dtype)
979
+
980
+ # coefficients
981
+ cc[interval+1:, ...] = c[interval:, ...]
982
+
983
+ for i in range(interval, interval-k, -1):
984
+ fac = (xval - tt[i]) / (tt[i+k+1] - tt[i])
985
+ cc[i, ...] = fac*c[i, ...] + (1. - fac)*c[i-1, ...]
986
+
987
+ cc[:interval - k+1, ...] = c[:interval - k+1, ...]
988
+
989
+ if periodic:
990
+ # c incorporate the boundary conditions for a periodic spline.
991
+ n = tt.shape[0]
992
+ nk = n - k - 1
993
+ n2k = n - 2*k - 1
994
+ T = tt[nk] - tt[k] # period
995
+
996
+ if interval >= nk - k:
997
+ # adjust the left-hand boundary knots & coefs
998
+ tt[:k] = tt[nk - k:nk] - T
999
+ cc[:k, ...] = cc[n2k:n2k + k, ...]
1000
+
1001
+ if interval <= 2*k-1:
1002
+ # adjust the right-hand boundary knots & coefs
1003
+ tt[n-k:] = tt[k+1:k+1+k] + T
1004
+ cc[n2k:n2k + k, ...] = cc[:k, ...]
1005
+
1006
+ return tt, cc
1007
+
1008
+
1009
+ #################################
1010
+ # Interpolating spline helpers #
1011
+ #################################
1012
+
1013
+ def _not_a_knot(x, k):
1014
+ """Given data x, construct the knot vector w/ not-a-knot BC.
1015
+ cf de Boor, XIII(12).
1016
+
1017
+ For even k, it's a bit ad hoc: Greville sites + omit 2nd and 2nd-to-last
1018
+ data points, a la not-a-knot.
1019
+ This seems to match what Dierckx does, too:
1020
+ https://github.com/scipy/scipy/blob/maintenance/1.11.x/scipy/interpolate/fitpack/fpcurf.f#L63-L80
1021
+ """
1022
+ x = np.asarray(x)
1023
+ if k % 2 == 1:
1024
+ k2 = (k + 1) // 2
1025
+ t = x.copy()
1026
+ else:
1027
+ k2 = k // 2
1028
+ t = (x[1:] + x[:-1]) / 2
1029
+
1030
+ t = t[k2:-k2]
1031
+ t = np.r_[(x[0],)*(k+1), t, (x[-1],)*(k+1)]
1032
+ return t
1033
+
1034
+
1035
+ def _augknt(x, k):
1036
+ """Construct a knot vector appropriate for the order-k interpolation."""
1037
+ return np.r_[(x[0],)*k, x, (x[-1],)*k]
1038
+
1039
+
1040
+ def _convert_string_aliases(deriv, target_shape):
1041
+ if isinstance(deriv, str):
1042
+ if deriv == "clamped":
1043
+ deriv = [(1, np.zeros(target_shape))]
1044
+ elif deriv == "natural":
1045
+ deriv = [(2, np.zeros(target_shape))]
1046
+ else:
1047
+ raise ValueError(f"Unknown boundary condition : {deriv}")
1048
+ return deriv
1049
+
1050
+
1051
+ def _process_deriv_spec(deriv):
1052
+ if deriv is not None:
1053
+ try:
1054
+ ords, vals = zip(*deriv)
1055
+ except TypeError as e:
1056
+ msg = ("Derivatives, `bc_type`, should be specified as a pair of "
1057
+ "iterables of pairs of (order, value).")
1058
+ raise ValueError(msg) from e
1059
+ else:
1060
+ ords, vals = [], []
1061
+ return np.atleast_1d(ords, vals)
1062
+
1063
+
1064
+ def _woodbury_algorithm(A, ur, ll, b, k):
1065
+ '''
1066
+ Solve a cyclic banded linear system with upper right
1067
+ and lower blocks of size ``(k-1) / 2`` using
1068
+ the Woodbury formula
1069
+
1070
+ Parameters
1071
+ ----------
1072
+ A : 2-D array, shape(k, n)
1073
+ Matrix of diagonals of original matrix (see
1074
+ ``solve_banded`` documentation).
1075
+ ur : 2-D array, shape(bs, bs)
1076
+ Upper right block matrix.
1077
+ ll : 2-D array, shape(bs, bs)
1078
+ Lower left block matrix.
1079
+ b : 1-D array, shape(n,)
1080
+ Vector of constant terms of the system of linear equations.
1081
+ k : int
1082
+ B-spline degree.
1083
+
1084
+ Returns
1085
+ -------
1086
+ c : 1-D array, shape(n,)
1087
+ Solution of the original system of linear equations.
1088
+
1089
+ Notes
1090
+ -----
1091
+ This algorithm works only for systems with banded matrix A plus
1092
+ a correction term U @ V.T, where the matrix U @ V.T gives upper right
1093
+ and lower left block of A
1094
+ The system is solved with the following steps:
1095
+ 1. New systems of linear equations are constructed:
1096
+ A @ z_i = u_i,
1097
+ u_i - column vector of U,
1098
+ i = 1, ..., k - 1
1099
+ 2. Matrix Z is formed from vectors z_i:
1100
+ Z = [ z_1 | z_2 | ... | z_{k - 1} ]
1101
+ 3. Matrix H = (1 + V.T @ Z)^{-1}
1102
+ 4. The system A' @ y = b is solved
1103
+ 5. x = y - Z @ (H @ V.T @ y)
1104
+ Also, ``n`` should be greater than ``k``, otherwise corner block
1105
+ elements will intersect with diagonals.
1106
+
1107
+ Examples
1108
+ --------
1109
+ Consider the case of n = 8, k = 5 (size of blocks - 2 x 2).
1110
+ The matrix of a system: U: V:
1111
+ x x x * * a b a b 0 0 0 0 1 0
1112
+ x x x x * * c 0 c 0 0 0 0 0 1
1113
+ x x x x x * * 0 0 0 0 0 0 0 0
1114
+ * x x x x x * 0 0 0 0 0 0 0 0
1115
+ * * x x x x x 0 0 0 0 0 0 0 0
1116
+ d * * x x x x 0 0 d 0 1 0 0 0
1117
+ e f * * x x x 0 0 e f 0 1 0 0
1118
+
1119
+ References
1120
+ ----------
1121
+ .. [1] William H. Press, Saul A. Teukolsky, William T. Vetterling
1122
+ and Brian P. Flannery, Numerical Recipes, 2007, Section 2.7.3
1123
+
1124
+ '''
1125
+ k_mod = k - k % 2
1126
+ bs = int((k - 1) / 2) + (k + 1) % 2
1127
+
1128
+ n = A.shape[1] + 1
1129
+ U = np.zeros((n - 1, k_mod))
1130
+ VT = np.zeros((k_mod, n - 1)) # V transpose
1131
+
1132
+ # upper right block
1133
+ U[:bs, :bs] = ur
1134
+ VT[np.arange(bs), np.arange(bs) - bs] = 1
1135
+
1136
+ # lower left block
1137
+ U[-bs:, -bs:] = ll
1138
+ VT[np.arange(bs) - bs, np.arange(bs)] = 1
1139
+
1140
+ Z = solve_banded((bs, bs), A, U)
1141
+
1142
+ H = solve(np.identity(k_mod) + VT @ Z, np.identity(k_mod))
1143
+
1144
+ y = solve_banded((bs, bs), A, b)
1145
+ c = y - Z @ (H @ (VT @ y))
1146
+
1147
+ return c
1148
+
1149
+
1150
+ def _periodic_knots(x, k):
1151
+ '''
1152
+ returns vector of nodes on circle
1153
+ '''
1154
+ xc = np.copy(x)
1155
+ n = len(xc)
1156
+ if k % 2 == 0:
1157
+ dx = np.diff(xc)
1158
+ xc[1: -1] -= dx[:-1] / 2
1159
+ dx = np.diff(xc)
1160
+ t = np.zeros(n + 2 * k)
1161
+ t[k: -k] = xc
1162
+ for i in range(0, k):
1163
+ # filling first `k` elements in descending order
1164
+ t[k - i - 1] = t[k - i] - dx[-(i % (n - 1)) - 1]
1165
+ # filling last `k` elements in ascending order
1166
+ t[-k + i] = t[-k + i - 1] + dx[i % (n - 1)]
1167
+ return t
1168
+
1169
+
1170
+ def _make_interp_per_full_matr(x, y, t, k):
1171
+ '''
1172
+ Returns a solution of a system for B-spline interpolation with periodic
1173
+ boundary conditions. First ``k - 1`` rows of matrix are conditions of
1174
+ periodicity (continuity of ``k - 1`` derivatives at the boundary points).
1175
+ Last ``n`` rows are interpolation conditions.
1176
+ RHS is ``k - 1`` zeros and ``n`` ordinates in this case.
1177
+
1178
+ Parameters
1179
+ ----------
1180
+ x : 1-D array, shape (n,)
1181
+ Values of x - coordinate of a given set of points.
1182
+ y : 1-D array, shape (n,)
1183
+ Values of y - coordinate of a given set of points.
1184
+ t : 1-D array, shape(n+2*k,)
1185
+ Vector of knots.
1186
+ k : int
1187
+ The maximum degree of spline
1188
+
1189
+ Returns
1190
+ -------
1191
+ c : 1-D array, shape (n+k-1,)
1192
+ B-spline coefficients
1193
+
1194
+ Notes
1195
+ -----
1196
+ ``t`` is supposed to be taken on circle.
1197
+
1198
+ '''
1199
+
1200
+ x, y, t = map(np.asarray, (x, y, t))
1201
+
1202
+ n = x.size
1203
+ # LHS: the colocation matrix + derivatives at edges
1204
+ matr = np.zeros((n + k - 1, n + k - 1))
1205
+
1206
+ # derivatives at x[0] and x[-1]:
1207
+ for i in range(k - 1):
1208
+ bb = _dierckx.evaluate_all_bspl(t, k, x[0], k, i + 1)
1209
+ matr[i, : k + 1] += bb
1210
+ bb = _dierckx.evaluate_all_bspl(t, k, x[-1], n + k - 1, i + 1)[:-1]
1211
+ matr[i, -k:] -= bb
1212
+
1213
+ # colocation matrix
1214
+ for i in range(n):
1215
+ xval = x[i]
1216
+ # find interval
1217
+ if xval == t[k]:
1218
+ left = k
1219
+ else:
1220
+ left = np.searchsorted(t, xval) - 1
1221
+
1222
+ # fill a row
1223
+ bb = _dierckx.evaluate_all_bspl(t, k, xval, left)
1224
+ matr[i + k - 1, left-k:left+1] = bb
1225
+
1226
+ # RHS
1227
+ b = np.r_[[0] * (k - 1), y]
1228
+
1229
+ c = solve(matr, b)
1230
+ return c
1231
+
1232
+
1233
+ def _handle_lhs_derivatives(t, k, xval, ab, kl, ku, deriv_ords, offset=0):
1234
+ """ Fill in the entries of the colocation matrix corresponding to known
1235
+ derivatives at `xval`.
1236
+
1237
+ The colocation matrix is in the banded storage, as prepared by _coloc.
1238
+ No error checking.
1239
+
1240
+ Parameters
1241
+ ----------
1242
+ t : ndarray, shape (nt + k + 1,)
1243
+ knots
1244
+ k : integer
1245
+ B-spline order
1246
+ xval : float
1247
+ The value at which to evaluate the derivatives at.
1248
+ ab : ndarray, shape(2*kl + ku + 1, nt), Fortran order
1249
+ B-spline colocation matrix.
1250
+ This argument is modified *in-place*.
1251
+ kl : integer
1252
+ Number of lower diagonals of ab.
1253
+ ku : integer
1254
+ Number of upper diagonals of ab.
1255
+ deriv_ords : 1D ndarray
1256
+ Orders of derivatives known at xval
1257
+ offset : integer, optional
1258
+ Skip this many rows of the matrix ab.
1259
+
1260
+ """
1261
+ # find where `xval` is in the knot vector, `t`
1262
+ left = _dierckx.find_interval(t, k, float(xval), k, False)
1263
+
1264
+ # compute and fill in the derivatives @ xval
1265
+ for row in range(deriv_ords.shape[0]):
1266
+ nu = deriv_ords[row]
1267
+ wrk = _dierckx.evaluate_all_bspl(t, k, xval, left, nu)
1268
+
1269
+ # if A were a full matrix, it would be just
1270
+ # ``A[row + offset, left-k:left+1] = bb``.
1271
+ for a in range(k+1):
1272
+ clmn = left - k + a
1273
+ ab[kl + ku + offset + row - clmn, clmn] = wrk[a]
1274
+
1275
+
1276
+ def _make_periodic_spline(x, y, t, k, axis):
1277
+ '''
1278
+ Compute the (coefficients of) interpolating B-spline with periodic
1279
+ boundary conditions.
1280
+
1281
+ Parameters
1282
+ ----------
1283
+ x : array_like, shape (n,)
1284
+ Abscissas.
1285
+ y : array_like, shape (n,)
1286
+ Ordinates.
1287
+ k : int
1288
+ B-spline degree.
1289
+ t : array_like, shape (n + 2 * k,).
1290
+ Knots taken on a circle, ``k`` on the left and ``k`` on the right
1291
+ of the vector ``x``.
1292
+
1293
+ Returns
1294
+ -------
1295
+ b : `BSpline` object
1296
+ A `BSpline` object of the degree ``k`` and with knots ``t``.
1297
+
1298
+ Notes
1299
+ -----
1300
+ The original system is formed by ``n + k - 1`` equations where the first
1301
+ ``k - 1`` of them stand for the ``k - 1`` derivatives continuity on the
1302
+ edges while the other equations correspond to an interpolating case
1303
+ (matching all the input points). Due to a special form of knot vector, it
1304
+ can be proved that in the original system the first and last ``k``
1305
+ coefficients of a spline function are the same, respectively. It follows
1306
+ from the fact that all ``k - 1`` derivatives are equal term by term at ends
1307
+ and that the matrix of the original system of linear equations is
1308
+ non-degenerate. So, we can reduce the number of equations to ``n - 1``
1309
+ (first ``k - 1`` equations could be reduced). Another trick of this
1310
+ implementation is cyclic shift of values of B-splines due to equality of
1311
+ ``k`` unknown coefficients. With this we can receive matrix of the system
1312
+ with upper right and lower left blocks, and ``k`` diagonals. It allows
1313
+ to use Woodbury formula to optimize the computations.
1314
+
1315
+ '''
1316
+ n = y.shape[0]
1317
+
1318
+ extradim = prod(y.shape[1:])
1319
+ y_new = y.reshape(n, extradim)
1320
+ c = np.zeros((n + k - 1, extradim))
1321
+
1322
+ # n <= k case is solved with full matrix
1323
+ if n <= k:
1324
+ for i in range(extradim):
1325
+ c[:, i] = _make_interp_per_full_matr(x, y_new[:, i], t, k)
1326
+ c = np.ascontiguousarray(c.reshape((n + k - 1,) + y.shape[1:]))
1327
+ return BSpline.construct_fast(t, c, k, extrapolate='periodic', axis=axis)
1328
+
1329
+ nt = len(t) - k - 1
1330
+
1331
+ # size of block elements
1332
+ kul = int(k / 2)
1333
+
1334
+ # kl = ku = k
1335
+ ab = np.zeros((3 * k + 1, nt), dtype=np.float64, order='F')
1336
+
1337
+ # upper right and lower left blocks
1338
+ ur = np.zeros((kul, kul))
1339
+ ll = np.zeros_like(ur)
1340
+
1341
+ # `offset` is made to shift all the non-zero elements to the end of the
1342
+ # matrix
1343
+ # NB: 1. drop the last element of `x` because `x[0] = x[-1] + T` & `y[0] == y[-1]`
1344
+ # 2. pass ab.T to _coloc to make it C-ordered; below it'll be fed to banded
1345
+ # LAPACK, which needs F-ordered arrays
1346
+ _dierckx._coloc(x[:-1], t, k, ab.T, k)
1347
+
1348
+ # remove zeros before the matrix
1349
+ ab = ab[-k - (k + 1) % 2:, :]
1350
+
1351
+ # The least elements in rows (except repetitions) are diagonals
1352
+ # of block matrices. Upper right matrix is an upper triangular
1353
+ # matrix while lower left is a lower triangular one.
1354
+ for i in range(kul):
1355
+ ur += np.diag(ab[-i - 1, i: kul], k=i)
1356
+ ll += np.diag(ab[i, -kul - (k % 2): n - 1 + 2 * kul - i], k=-i)
1357
+
1358
+ # remove elements that occur in the last point
1359
+ # (first and last points are equivalent)
1360
+ A = ab[:, kul: -k + kul]
1361
+
1362
+ for i in range(extradim):
1363
+ cc = _woodbury_algorithm(A, ur, ll, y_new[:, i][:-1], k)
1364
+ c[:, i] = np.concatenate((cc[-kul:], cc, cc[:kul + k % 2]))
1365
+ c = np.ascontiguousarray(c.reshape((n + k - 1,) + y.shape[1:]))
1366
+ return BSpline.construct_fast(t, c, k, extrapolate='periodic', axis=axis)
1367
+
1368
+
1369
+ def make_interp_spline(x, y, k=3, t=None, bc_type=None, axis=0,
1370
+ check_finite=True):
1371
+ """Create an interpolating B-spline with specified degree and boundary conditions.
1372
+
1373
+ Parameters
1374
+ ----------
1375
+ x : array_like, shape (n,)
1376
+ Abscissas.
1377
+ y : array_like, shape (n, ...)
1378
+ Ordinates.
1379
+ k : int, optional
1380
+ B-spline degree. Default is cubic, ``k = 3``.
1381
+ t : array_like, shape (nt + k + 1,), optional.
1382
+ Knots.
1383
+ The number of knots needs to agree with the number of data points and
1384
+ the number of derivatives at the edges. Specifically, ``nt - n`` must
1385
+ equal ``len(deriv_l) + len(deriv_r)``.
1386
+ bc_type : 2-tuple or None
1387
+ Boundary conditions.
1388
+ Default is None, which means choosing the boundary conditions
1389
+ automatically. Otherwise, it must be a length-two tuple where the first
1390
+ element (``deriv_l``) sets the boundary conditions at ``x[0]`` and
1391
+ the second element (``deriv_r``) sets the boundary conditions at
1392
+ ``x[-1]``. Each of these must be an iterable of pairs
1393
+ ``(order, value)`` which gives the values of derivatives of specified
1394
+ orders at the given edge of the interpolation interval.
1395
+ Alternatively, the following string aliases are recognized:
1396
+
1397
+ * ``"clamped"``: The first derivatives at the ends are zero. This is
1398
+ equivalent to ``bc_type=([(1, 0.0)], [(1, 0.0)])``.
1399
+ * ``"natural"``: The second derivatives at ends are zero. This is
1400
+ equivalent to ``bc_type=([(2, 0.0)], [(2, 0.0)])``.
1401
+ * ``"not-a-knot"`` (default): The first and second segments are the
1402
+ same polynomial. This is equivalent to having ``bc_type=None``.
1403
+ * ``"periodic"``: The values and the first ``k-1`` derivatives at the
1404
+ ends are equivalent.
1405
+
1406
+ axis : int, optional
1407
+ Interpolation axis. Default is 0.
1408
+ check_finite : bool, optional
1409
+ Whether to check that the input arrays contain only finite numbers.
1410
+ Disabling may give a performance gain, but may result in problems
1411
+ (crashes, non-termination) if the inputs do contain infinities or NaNs.
1412
+ Default is True.
1413
+
1414
+ Returns
1415
+ -------
1416
+ b : `BSpline` object
1417
+ A `BSpline` object of the degree ``k`` and with knots ``t``.
1418
+
1419
+ See Also
1420
+ --------
1421
+ BSpline : base class representing the B-spline objects
1422
+ CubicSpline : a cubic spline in the polynomial basis
1423
+ make_lsq_spline : a similar factory function for spline fitting
1424
+ UnivariateSpline : a wrapper over FITPACK spline fitting routines
1425
+ splrep : a wrapper over FITPACK spline fitting routines
1426
+
1427
+ Examples
1428
+ --------
1429
+
1430
+ Use cubic interpolation on Chebyshev nodes:
1431
+
1432
+ >>> import numpy as np
1433
+ >>> import matplotlib.pyplot as plt
1434
+ >>> def cheb_nodes(N):
1435
+ ... jj = 2.*np.arange(N) + 1
1436
+ ... x = np.cos(np.pi * jj / 2 / N)[::-1]
1437
+ ... return x
1438
+
1439
+ >>> x = cheb_nodes(20)
1440
+ >>> y = np.sqrt(1 - x**2)
1441
+
1442
+ >>> from scipy.interpolate import BSpline, make_interp_spline
1443
+ >>> b = make_interp_spline(x, y)
1444
+ >>> np.allclose(b(x), y)
1445
+ True
1446
+
1447
+ Note that the default is a cubic spline with a not-a-knot boundary condition
1448
+
1449
+ >>> b.k
1450
+ 3
1451
+
1452
+ Here we use a 'natural' spline, with zero 2nd derivatives at edges:
1453
+
1454
+ >>> l, r = [(2, 0.0)], [(2, 0.0)]
1455
+ >>> b_n = make_interp_spline(x, y, bc_type=(l, r)) # or, bc_type="natural"
1456
+ >>> np.allclose(b_n(x), y)
1457
+ True
1458
+ >>> x0, x1 = x[0], x[-1]
1459
+ >>> np.allclose([b_n(x0, 2), b_n(x1, 2)], [0, 0])
1460
+ True
1461
+
1462
+ Interpolation of parametric curves is also supported. As an example, we
1463
+ compute a discretization of a snail curve in polar coordinates
1464
+
1465
+ >>> phi = np.linspace(0, 2.*np.pi, 40)
1466
+ >>> r = 0.3 + np.cos(phi)
1467
+ >>> x, y = r*np.cos(phi), r*np.sin(phi) # convert to Cartesian coordinates
1468
+
1469
+ Build an interpolating curve, parameterizing it by the angle
1470
+
1471
+ >>> spl = make_interp_spline(phi, np.c_[x, y])
1472
+
1473
+ Evaluate the interpolant on a finer grid (note that we transpose the result
1474
+ to unpack it into a pair of x- and y-arrays)
1475
+
1476
+ >>> phi_new = np.linspace(0, 2.*np.pi, 100)
1477
+ >>> x_new, y_new = spl(phi_new).T
1478
+
1479
+ Plot the result
1480
+
1481
+ >>> plt.plot(x, y, 'o')
1482
+ >>> plt.plot(x_new, y_new, '-')
1483
+ >>> plt.show()
1484
+
1485
+ Build a B-spline curve with 2 dimensional y
1486
+
1487
+ >>> x = np.linspace(0, 2*np.pi, 10)
1488
+ >>> y = np.array([np.sin(x), np.cos(x)])
1489
+
1490
+ Periodic condition is satisfied because y coordinates of points on the ends
1491
+ are equivalent
1492
+
1493
+ >>> ax = plt.axes(projection='3d')
1494
+ >>> xx = np.linspace(0, 2*np.pi, 100)
1495
+ >>> bspl = make_interp_spline(x, y, k=5, bc_type='periodic', axis=1)
1496
+ >>> ax.plot3D(xx, *bspl(xx))
1497
+ >>> ax.scatter3D(x, *y, color='red')
1498
+ >>> plt.show()
1499
+
1500
+ """
1501
+ # convert string aliases for the boundary conditions
1502
+ if bc_type is None or bc_type == 'not-a-knot' or bc_type == 'periodic':
1503
+ deriv_l, deriv_r = None, None
1504
+ elif isinstance(bc_type, str):
1505
+ deriv_l, deriv_r = bc_type, bc_type
1506
+ else:
1507
+ try:
1508
+ deriv_l, deriv_r = bc_type
1509
+ except TypeError as e:
1510
+ raise ValueError(f"Unknown boundary condition: {bc_type}") from e
1511
+
1512
+ y = np.asarray(y)
1513
+
1514
+ axis = normalize_axis_index(axis, y.ndim)
1515
+
1516
+ x = _as_float_array(x, check_finite)
1517
+ y = _as_float_array(y, check_finite)
1518
+
1519
+ y = np.moveaxis(y, axis, 0) # now internally interp axis is zero
1520
+
1521
+ # sanity check the input
1522
+ if bc_type == 'periodic' and not np.allclose(y[0], y[-1], atol=1e-15):
1523
+ raise ValueError("First and last points does not match while "
1524
+ "periodic case expected")
1525
+ if x.size != y.shape[0]:
1526
+ raise ValueError(f'Shapes of x {x.shape} and y {y.shape} are incompatible')
1527
+ if np.any(x[1:] == x[:-1]):
1528
+ raise ValueError("Expect x to not have duplicates")
1529
+ if x.ndim != 1 or np.any(x[1:] < x[:-1]):
1530
+ raise ValueError("Expect x to be a 1D strictly increasing sequence.")
1531
+
1532
+ # special-case k=0 right away
1533
+ if k == 0:
1534
+ if any(_ is not None for _ in (t, deriv_l, deriv_r)):
1535
+ raise ValueError("Too much info for k=0: t and bc_type can only "
1536
+ "be None.")
1537
+ t = np.r_[x, x[-1]]
1538
+ c = np.asarray(y)
1539
+ c = np.ascontiguousarray(c, dtype=_get_dtype(c.dtype))
1540
+ return BSpline.construct_fast(t, c, k, axis=axis)
1541
+
1542
+ # special-case k=1 (e.g., Lyche and Morken, Eq.(2.16))
1543
+ if k == 1 and t is None:
1544
+ if not (deriv_l is None and deriv_r is None):
1545
+ raise ValueError("Too much info for k=1: bc_type can only be None.")
1546
+ t = np.r_[x[0], x, x[-1]]
1547
+ c = np.asarray(y)
1548
+ c = np.ascontiguousarray(c, dtype=_get_dtype(c.dtype))
1549
+ return BSpline.construct_fast(t, c, k, axis=axis)
1550
+
1551
+ k = operator.index(k)
1552
+
1553
+ if bc_type == 'periodic' and t is not None:
1554
+ raise NotImplementedError("For periodic case t is constructed "
1555
+ "automatically and can not be passed "
1556
+ "manually")
1557
+
1558
+ # come up with a sensible knot vector, if needed
1559
+ if t is None:
1560
+ if deriv_l is None and deriv_r is None:
1561
+ if bc_type == 'periodic':
1562
+ t = _periodic_knots(x, k)
1563
+ else:
1564
+ t = _not_a_knot(x, k)
1565
+ else:
1566
+ t = _augknt(x, k)
1567
+
1568
+ t = _as_float_array(t, check_finite)
1569
+
1570
+ if k < 0:
1571
+ raise ValueError("Expect non-negative k.")
1572
+ if t.ndim != 1 or np.any(t[1:] < t[:-1]):
1573
+ raise ValueError("Expect t to be a 1-D sorted array_like.")
1574
+ if t.size < x.size + k + 1:
1575
+ raise ValueError(f"Got {t.size} knots, need at least {x.size + k + 1}.")
1576
+ if (x[0] < t[k]) or (x[-1] > t[-k]):
1577
+ raise ValueError(f'Out of bounds w/ x = {x}.')
1578
+
1579
+ if bc_type == 'periodic':
1580
+ return _make_periodic_spline(x, y, t, k, axis)
1581
+
1582
+ # Here : deriv_l, r = [(nu, value), ...]
1583
+ deriv_l = _convert_string_aliases(deriv_l, y.shape[1:])
1584
+ deriv_l_ords, deriv_l_vals = _process_deriv_spec(deriv_l)
1585
+ nleft = deriv_l_ords.shape[0]
1586
+
1587
+ deriv_r = _convert_string_aliases(deriv_r, y.shape[1:])
1588
+ deriv_r_ords, deriv_r_vals = _process_deriv_spec(deriv_r)
1589
+ nright = deriv_r_ords.shape[0]
1590
+
1591
+ if not all(0 <= i <= k for i in deriv_l_ords):
1592
+ raise ValueError(f"Bad boundary conditions at {x[0]}.")
1593
+
1594
+ if not all(0 <= i <= k for i in deriv_r_ords):
1595
+ raise ValueError(f"Bad boundary conditions at {x[-1]}.")
1596
+
1597
+ # have `n` conditions for `nt` coefficients; need nt-n derivatives
1598
+ n = x.size
1599
+ nt = t.size - k - 1
1600
+
1601
+ if nt - n != nleft + nright:
1602
+ raise ValueError("The number of derivatives at boundaries does not "
1603
+ f"match: expected {nt-n}, got {nleft}+{nright}")
1604
+
1605
+ # bail out if the `y` array is zero-sized
1606
+ if y.size == 0:
1607
+ c = np.zeros((nt,) + y.shape[1:], dtype=float)
1608
+ return BSpline.construct_fast(t, c, k, axis=axis)
1609
+
1610
+ # set up the LHS: the colocation matrix + derivatives at boundaries
1611
+ # NB: ab is in F order for banded LAPACK; _coloc needs C-ordered arrays,
1612
+ # this pass ab.T into _coloc
1613
+ kl = ku = k
1614
+ ab = np.zeros((2*kl + ku + 1, nt), dtype=np.float64, order='F')
1615
+ _dierckx._coloc(x, t, k, ab.T, nleft)
1616
+ if nleft > 0:
1617
+ _handle_lhs_derivatives(t, k, x[0], ab, kl, ku, deriv_l_ords)
1618
+ if nright > 0:
1619
+ _handle_lhs_derivatives(t, k, x[-1], ab, kl, ku, deriv_r_ords,
1620
+ offset=nt-nright)
1621
+
1622
+ # set up the RHS: values to interpolate (+ derivative values, if any)
1623
+ extradim = prod(y.shape[1:])
1624
+ rhs = np.empty((nt, extradim), dtype=y.dtype)
1625
+ if nleft > 0:
1626
+ rhs[:nleft] = deriv_l_vals.reshape(-1, extradim)
1627
+ rhs[nleft:nt - nright] = y.reshape(-1, extradim)
1628
+ if nright > 0:
1629
+ rhs[nt - nright:] = deriv_r_vals.reshape(-1, extradim)
1630
+
1631
+ # solve Ab @ x = rhs; this is the relevant part of linalg.solve_banded
1632
+ if check_finite:
1633
+ ab, rhs = map(np.asarray_chkfinite, (ab, rhs))
1634
+ gbsv, = get_lapack_funcs(('gbsv',), (ab, rhs))
1635
+ lu, piv, c, info = gbsv(kl, ku, ab, rhs,
1636
+ overwrite_ab=True, overwrite_b=True)
1637
+
1638
+ if info > 0:
1639
+ raise LinAlgError("Colocation matrix is singular.")
1640
+ elif info < 0:
1641
+ raise ValueError(f'illegal value in {-info}-th argument of internal gbsv')
1642
+ c = np.ascontiguousarray(c.reshape((nt,) + y.shape[1:]))
1643
+ return BSpline.construct_fast(t, c, k, axis=axis)
1644
+
1645
+
1646
+ def make_lsq_spline(x, y, t, k=3, w=None, axis=0, check_finite=True, *, method="qr"):
1647
+ r"""Create a smoothing B-spline satisfying the Least SQuares (LSQ) criterion.
1648
+
1649
+ The result is a linear combination
1650
+
1651
+ .. math::
1652
+
1653
+ S(x) = \sum_j c_j B_j(x; t)
1654
+
1655
+ of the B-spline basis elements, :math:`B_j(x; t)`, which minimizes
1656
+
1657
+ .. math::
1658
+
1659
+ \sum_{j} \left( w_j \times (S(x_j) - y_j) \right)^2
1660
+
1661
+ Parameters
1662
+ ----------
1663
+ x : array_like, shape (m,)
1664
+ Abscissas.
1665
+ y : array_like, shape (m, ...)
1666
+ Ordinates.
1667
+ t : array_like, shape (n + k + 1,).
1668
+ Knots.
1669
+ Knots and data points must satisfy Schoenberg-Whitney conditions.
1670
+ k : int, optional
1671
+ B-spline degree. Default is cubic, ``k = 3``.
1672
+ w : array_like, shape (m,), optional
1673
+ Weights for spline fitting. Must be positive. If ``None``,
1674
+ then weights are all equal.
1675
+ Default is ``None``.
1676
+ axis : int, optional
1677
+ Interpolation axis. Default is zero.
1678
+ check_finite : bool, optional
1679
+ Whether to check that the input arrays contain only finite numbers.
1680
+ Disabling may give a performance gain, but may result in problems
1681
+ (crashes, non-termination) if the inputs do contain infinities or NaNs.
1682
+ Default is True.
1683
+ method : str, optional
1684
+ Method for solving the linear LSQ problem. Allowed values are "norm-eq"
1685
+ (Explicitly construct and solve the normal system of equations), and
1686
+ "qr" (Use the QR factorization of the design matrix).
1687
+ Default is "qr".
1688
+
1689
+ Returns
1690
+ -------
1691
+ b : `BSpline` object
1692
+ A `BSpline` object of the degree ``k`` with knots ``t``.
1693
+
1694
+ See Also
1695
+ --------
1696
+ BSpline : base class representing the B-spline objects
1697
+ make_interp_spline : a similar factory function for interpolating splines
1698
+ LSQUnivariateSpline : a FITPACK-based spline fitting routine
1699
+ splrep : a FITPACK-based fitting routine
1700
+
1701
+ Notes
1702
+ -----
1703
+ The number of data points must be larger than the spline degree ``k``.
1704
+
1705
+ Knots ``t`` must satisfy the Schoenberg-Whitney conditions,
1706
+ i.e., there must be a subset of data points ``x[j]`` such that
1707
+ ``t[j] < x[j] < t[j+k+1]``, for ``j=0, 1,...,n-k-2``.
1708
+
1709
+ Examples
1710
+ --------
1711
+ Generate some noisy data:
1712
+
1713
+ >>> import numpy as np
1714
+ >>> import matplotlib.pyplot as plt
1715
+ >>> rng = np.random.default_rng()
1716
+ >>> x = np.linspace(-3, 3, 50)
1717
+ >>> y = np.exp(-x**2) + 0.1 * rng.standard_normal(50)
1718
+
1719
+ Now fit a smoothing cubic spline with a pre-defined internal knots.
1720
+ Here we make the knot vector (k+1)-regular by adding boundary knots:
1721
+
1722
+ >>> from scipy.interpolate import make_lsq_spline, BSpline
1723
+ >>> t = [-1, 0, 1]
1724
+ >>> k = 3
1725
+ >>> t = np.r_[(x[0],)*(k+1),
1726
+ ... t,
1727
+ ... (x[-1],)*(k+1)]
1728
+ >>> spl = make_lsq_spline(x, y, t, k)
1729
+
1730
+ For comparison, we also construct an interpolating spline for the same
1731
+ set of data:
1732
+
1733
+ >>> from scipy.interpolate import make_interp_spline
1734
+ >>> spl_i = make_interp_spline(x, y)
1735
+
1736
+ Plot both:
1737
+
1738
+ >>> xs = np.linspace(-3, 3, 100)
1739
+ >>> plt.plot(x, y, 'ro', ms=5)
1740
+ >>> plt.plot(xs, spl(xs), 'g-', lw=3, label='LSQ spline')
1741
+ >>> plt.plot(xs, spl_i(xs), 'b-', lw=3, alpha=0.7, label='interp spline')
1742
+ >>> plt.legend(loc='best')
1743
+ >>> plt.show()
1744
+
1745
+ **NaN handling**: If the input arrays contain ``nan`` values, the result is
1746
+ not useful since the underlying spline fitting routines cannot deal with
1747
+ ``nan``. A workaround is to use zero weights for not-a-number data points:
1748
+
1749
+ >>> y[8] = np.nan
1750
+ >>> w = np.isnan(y)
1751
+ >>> y[w] = 0.
1752
+ >>> tck = make_lsq_spline(x, y, t, w=~w)
1753
+
1754
+ Notice the need to replace a ``nan`` by a numerical value (precise value
1755
+ does not matter as long as the corresponding weight is zero.)
1756
+
1757
+ """
1758
+ x = _as_float_array(x, check_finite)
1759
+ y = _as_float_array(y, check_finite)
1760
+ t = _as_float_array(t, check_finite)
1761
+ if w is not None:
1762
+ w = _as_float_array(w, check_finite)
1763
+ else:
1764
+ w = np.ones_like(x)
1765
+ k = operator.index(k)
1766
+
1767
+ axis = normalize_axis_index(axis, y.ndim)
1768
+
1769
+ y = np.moveaxis(y, axis, 0) # now internally interp axis is zero
1770
+ if not y.flags.c_contiguous:
1771
+ # C routines in _dierckx currently require C contiguity
1772
+ y = y.copy(order='C')
1773
+
1774
+ if x.ndim != 1:
1775
+ raise ValueError("Expect x to be a 1-D sequence.")
1776
+ if x.shape[0] < k+1:
1777
+ raise ValueError("Need more x points.")
1778
+ if k < 0:
1779
+ raise ValueError("Expect non-negative k.")
1780
+ if t.ndim != 1 or np.any(t[1:] - t[:-1] < 0):
1781
+ raise ValueError("Expect t to be a 1D strictly increasing sequence.")
1782
+ if x.size != y.shape[0]:
1783
+ raise ValueError(f'Shapes of x {x.shape} and y {y.shape} are incompatible')
1784
+ if k > 0 and np.any((x < t[k]) | (x > t[-k])):
1785
+ raise ValueError(f'Out of bounds w/ x = {x}.')
1786
+ if x.size != w.size:
1787
+ raise ValueError(f'Shapes of x {x.shape} and w {w.shape} are incompatible')
1788
+ if method == "norm-eq" and np.any(x[1:] - x[:-1] <= 0):
1789
+ raise ValueError("Expect x to be a 1D strictly increasing sequence.")
1790
+ if method == "qr" and any(x[1:] - x[:-1] < 0):
1791
+ raise ValueError("Expect x to be a 1D non-decreasing sequence.")
1792
+
1793
+ # number of coefficients
1794
+ n = t.size - k - 1
1795
+
1796
+ # complex y: view as float, preserve the length
1797
+ was_complex = y.dtype.kind == 'c'
1798
+ yy = y.view(float)
1799
+ if was_complex and y.ndim == 1:
1800
+ yy = yy.reshape(y.shape[0], 2)
1801
+
1802
+ # multiple r.h.s
1803
+ extradim = prod(yy.shape[1:])
1804
+ yy = yy.reshape(-1, extradim)
1805
+
1806
+ # complex y: view as float, preserve the length
1807
+ was_complex = y.dtype.kind == 'c'
1808
+ yy = y.view(float)
1809
+ if was_complex and y.ndim == 1:
1810
+ yy = yy.reshape(y.shape[0], 2)
1811
+
1812
+ # multiple r.h.s
1813
+ extradim = prod(yy.shape[1:])
1814
+ yy = yy.reshape(-1, extradim)
1815
+
1816
+ if method == "norm-eq":
1817
+ # construct A.T @ A and rhs with A the colocation matrix, and
1818
+ # rhs = A.T @ y for solving the LSQ problem ``A.T @ A @ c = A.T @ y``
1819
+ lower = True
1820
+ ab = np.zeros((k+1, n), dtype=np.float64, order='F')
1821
+ rhs = np.zeros((n, extradim), dtype=np.float64)
1822
+ _dierckx._norm_eq_lsq(x, t, k,
1823
+ yy,
1824
+ w,
1825
+ ab.T, rhs)
1826
+
1827
+ # undo complex -> float and flattening the trailing dims
1828
+ if was_complex:
1829
+ rhs = rhs.view(complex)
1830
+
1831
+ rhs = rhs.reshape((n,) + y.shape[1:])
1832
+
1833
+ # have observation matrix & rhs, can solve the LSQ problem
1834
+ cho_decomp = cholesky_banded(ab, overwrite_ab=True, lower=lower,
1835
+ check_finite=check_finite)
1836
+ m = rhs.shape[0]
1837
+ c = cho_solve_banded((cho_decomp, lower), rhs.reshape(m, -1), overwrite_b=True,
1838
+ check_finite=check_finite).reshape(rhs.shape)
1839
+ elif method == "qr":
1840
+ _, _, c = _lsq_solve_qr(x, yy, t, k, w)
1841
+
1842
+ if was_complex:
1843
+ c = c.view(complex)
1844
+
1845
+ else:
1846
+ raise ValueError(f"Unknown {method =}.")
1847
+
1848
+
1849
+ # restore the shape of `c` for both single and multiple r.h.s.
1850
+ c = c.reshape((n,) + y.shape[1:])
1851
+ c = np.ascontiguousarray(c)
1852
+ return BSpline.construct_fast(t, c, k, axis=axis)
1853
+
1854
+
1855
+ ######################
1856
+ # LSQ spline helpers #
1857
+ ######################
1858
+
1859
+ def _lsq_solve_qr(x, y, t, k, w):
1860
+ """Solve for the LSQ spline coeffs given x, y and knots.
1861
+
1862
+ `y` is always 2D: for 1D data, the shape is ``(m, 1)``.
1863
+ `w` is always 1D: one weight value per `x` value.
1864
+
1865
+ """
1866
+ assert y.ndim == 2
1867
+
1868
+ y_w = y * w[:, None]
1869
+ A, offset, nc = _dierckx.data_matrix(x, t, k, w)
1870
+ _dierckx.qr_reduce(A, offset, nc, y_w) # modifies arguments in-place
1871
+ c = _dierckx.fpback(A, nc, y_w)
1872
+
1873
+ return A, y_w, c
1874
+
1875
+
1876
+ #############################
1877
+ # Smoothing spline helpers #
1878
+ #############################
1879
+
1880
+ def _compute_optimal_gcv_parameter(X, wE, y, w):
1881
+ """
1882
+ Returns an optimal regularization parameter from the GCV criteria [1].
1883
+
1884
+ Parameters
1885
+ ----------
1886
+ X : array, shape (5, n)
1887
+ 5 bands of the design matrix ``X`` stored in LAPACK banded storage.
1888
+ wE : array, shape (5, n)
1889
+ 5 bands of the penalty matrix :math:`W^{-1} E` stored in LAPACK banded
1890
+ storage.
1891
+ y : array, shape (n,)
1892
+ Ordinates.
1893
+ w : array, shape (n,)
1894
+ Vector of weights.
1895
+
1896
+ Returns
1897
+ -------
1898
+ lam : float
1899
+ An optimal from the GCV criteria point of view regularization
1900
+ parameter.
1901
+
1902
+ Notes
1903
+ -----
1904
+ No checks are performed.
1905
+
1906
+ References
1907
+ ----------
1908
+ .. [1] G. Wahba, "Estimating the smoothing parameter" in Spline models
1909
+ for observational data, Philadelphia, Pennsylvania: Society for
1910
+ Industrial and Applied Mathematics, 1990, pp. 45-65.
1911
+ :doi:`10.1137/1.9781611970128`
1912
+
1913
+ """
1914
+
1915
+ def compute_banded_symmetric_XT_W_Y(X, w, Y):
1916
+ """
1917
+ Assuming that the product :math:`X^T W Y` is symmetric and both ``X``
1918
+ and ``Y`` are 5-banded, compute the unique bands of the product.
1919
+
1920
+ Parameters
1921
+ ----------
1922
+ X : array, shape (5, n)
1923
+ 5 bands of the matrix ``X`` stored in LAPACK banded storage.
1924
+ w : array, shape (n,)
1925
+ Array of weights
1926
+ Y : array, shape (5, n)
1927
+ 5 bands of the matrix ``Y`` stored in LAPACK banded storage.
1928
+
1929
+ Returns
1930
+ -------
1931
+ res : array, shape (4, n)
1932
+ The result of the product :math:`X^T Y` stored in the banded way.
1933
+
1934
+ Notes
1935
+ -----
1936
+ As far as the matrices ``X`` and ``Y`` are 5-banded, their product
1937
+ :math:`X^T W Y` is 7-banded. It is also symmetric, so we can store only
1938
+ unique diagonals.
1939
+
1940
+ """
1941
+ # compute W Y
1942
+ W_Y = np.copy(Y)
1943
+
1944
+ W_Y[2] *= w
1945
+ for i in range(2):
1946
+ W_Y[i, 2 - i:] *= w[:-2 + i]
1947
+ W_Y[3 + i, :-1 - i] *= w[1 + i:]
1948
+
1949
+ n = X.shape[1]
1950
+ res = np.zeros((4, n))
1951
+ for i in range(n):
1952
+ for j in range(min(n-i, 4)):
1953
+ res[-j-1, i + j] = sum(X[j:, i] * W_Y[:5-j, i + j])
1954
+ return res
1955
+
1956
+ def compute_b_inv(A):
1957
+ """
1958
+ Inverse 3 central bands of matrix :math:`A=U^T D^{-1} U` assuming that
1959
+ ``U`` is a unit upper triangular banded matrix using an algorithm
1960
+ proposed in [1].
1961
+
1962
+ Parameters
1963
+ ----------
1964
+ A : array, shape (4, n)
1965
+ Matrix to inverse, stored in LAPACK banded storage.
1966
+
1967
+ Returns
1968
+ -------
1969
+ B : array, shape (4, n)
1970
+ 3 unique bands of the symmetric matrix that is an inverse to ``A``.
1971
+ The first row is filled with zeros.
1972
+
1973
+ Notes
1974
+ -----
1975
+ The algorithm is based on the cholesky decomposition and, therefore,
1976
+ in case matrix ``A`` is close to not positive defined, the function
1977
+ raises LinalgError.
1978
+
1979
+ Both matrices ``A`` and ``B`` are stored in LAPACK banded storage.
1980
+
1981
+ References
1982
+ ----------
1983
+ .. [1] M. F. Hutchinson and F. R. de Hoog, "Smoothing noisy data with
1984
+ spline functions," Numerische Mathematik, vol. 47, no. 1,
1985
+ pp. 99-106, 1985.
1986
+ :doi:`10.1007/BF01389878`
1987
+
1988
+ """
1989
+
1990
+ def find_b_inv_elem(i, j, U, D, B):
1991
+ rng = min(3, n - i - 1)
1992
+ rng_sum = 0.
1993
+ if j == 0:
1994
+ # use 2-nd formula from [1]
1995
+ for k in range(1, rng + 1):
1996
+ rng_sum -= U[-k - 1, i + k] * B[-k - 1, i + k]
1997
+ rng_sum += D[i]
1998
+ B[-1, i] = rng_sum
1999
+ else:
2000
+ # use 1-st formula from [1]
2001
+ for k in range(1, rng + 1):
2002
+ diag = abs(k - j)
2003
+ ind = i + min(k, j)
2004
+ rng_sum -= U[-k - 1, i + k] * B[-diag - 1, ind + diag]
2005
+ B[-j - 1, i + j] = rng_sum
2006
+
2007
+ U = cholesky_banded(A)
2008
+ for i in range(2, 5):
2009
+ U[-i, i-1:] /= U[-1, :-i+1]
2010
+ D = 1. / (U[-1])**2
2011
+ U[-1] /= U[-1]
2012
+
2013
+ n = U.shape[1]
2014
+
2015
+ B = np.zeros(shape=(4, n))
2016
+ for i in range(n - 1, -1, -1):
2017
+ for j in range(min(3, n - i - 1), -1, -1):
2018
+ find_b_inv_elem(i, j, U, D, B)
2019
+ # the first row contains garbage and should be removed
2020
+ B[0] = [0.] * n
2021
+ return B
2022
+
2023
+ def _gcv(lam, X, XtWX, wE, XtE, y):
2024
+ r"""
2025
+ Computes the generalized cross-validation criteria [1].
2026
+
2027
+ Parameters
2028
+ ----------
2029
+ lam : float, (:math:`\lambda \geq 0`)
2030
+ Regularization parameter.
2031
+ X : array, shape (5, n)
2032
+ Matrix is stored in LAPACK banded storage.
2033
+ XtWX : array, shape (4, n)
2034
+ Product :math:`X^T W X` stored in LAPACK banded storage.
2035
+ wE : array, shape (5, n)
2036
+ Matrix :math:`W^{-1} E` stored in LAPACK banded storage.
2037
+ XtE : array, shape (4, n)
2038
+ Product :math:`X^T E` stored in LAPACK banded storage.
2039
+
2040
+ Returns
2041
+ -------
2042
+ res : float
2043
+ Value of the GCV criteria with the regularization parameter
2044
+ :math:`\lambda`.
2045
+
2046
+ Notes
2047
+ -----
2048
+ Criteria is computed from the formula (1.3.2) [3]:
2049
+
2050
+ .. math:
2051
+
2052
+ GCV(\lambda) = \dfrac{1}{n} \sum\limits_{k = 1}^{n} \dfrac{ \left(
2053
+ y_k - f_{\lambda}(x_k) \right)^2}{\left( 1 - \Tr{A}/n\right)^2}$.
2054
+ The criteria is discussed in section 1.3 [3].
2055
+
2056
+ The numerator is computed using (2.2.4) [3] and the denominator is
2057
+ computed using an algorithm from [2] (see in the ``compute_b_inv``
2058
+ function).
2059
+
2060
+ References
2061
+ ----------
2062
+ .. [1] G. Wahba, "Estimating the smoothing parameter" in Spline models
2063
+ for observational data, Philadelphia, Pennsylvania: Society for
2064
+ Industrial and Applied Mathematics, 1990, pp. 45-65.
2065
+ :doi:`10.1137/1.9781611970128`
2066
+ .. [2] M. F. Hutchinson and F. R. de Hoog, "Smoothing noisy data with
2067
+ spline functions," Numerische Mathematik, vol. 47, no. 1,
2068
+ pp. 99-106, 1985.
2069
+ :doi:`10.1007/BF01389878`
2070
+ .. [3] E. Zemlyanoy, "Generalized cross-validation smoothing splines",
2071
+ BSc thesis, 2022. Might be available (in Russian)
2072
+ `here <https://www.hse.ru/ba/am/students/diplomas/620910604>`_
2073
+
2074
+ """
2075
+ # Compute the numerator from (2.2.4) [3]
2076
+ n = X.shape[1]
2077
+ c = solve_banded((2, 2), X + lam * wE, y)
2078
+ res = np.zeros(n)
2079
+ # compute ``W^{-1} E c`` with respect to banded-storage of ``E``
2080
+ tmp = wE * c
2081
+ for i in range(n):
2082
+ for j in range(max(0, i - n + 3), min(5, i + 3)):
2083
+ res[i] += tmp[j, i + 2 - j]
2084
+ numer = np.linalg.norm(lam * res)**2 / n
2085
+
2086
+ # compute the denominator
2087
+ lhs = XtWX + lam * XtE
2088
+ try:
2089
+ b_banded = compute_b_inv(lhs)
2090
+ # compute the trace of the product b_banded @ XtX
2091
+ tr = b_banded * XtWX
2092
+ tr[:-1] *= 2
2093
+ # find the denominator
2094
+ denom = (1 - sum(sum(tr)) / n)**2
2095
+ except LinAlgError:
2096
+ # cholesky decomposition cannot be performed
2097
+ raise ValueError('Seems like the problem is ill-posed')
2098
+
2099
+ res = numer / denom
2100
+
2101
+ return res
2102
+
2103
+ n = X.shape[1]
2104
+
2105
+ XtWX = compute_banded_symmetric_XT_W_Y(X, w, X)
2106
+ XtE = compute_banded_symmetric_XT_W_Y(X, w, wE)
2107
+
2108
+ if y.ndim == 1:
2109
+ gcv_est = minimize_scalar(
2110
+ _gcv, bounds=(0, n), method='Bounded', args=(X, XtWX, wE, XtE, y)
2111
+ )
2112
+ if gcv_est.success:
2113
+ return gcv_est.x
2114
+ raise ValueError(f"Unable to find minimum of the GCV "
2115
+ f"function: {gcv_est.message}")
2116
+ elif y.ndim == 2:
2117
+ gcv_est = np.empty(y.shape[1])
2118
+ for i in range(y.shape[1]):
2119
+ est = minimize_scalar(
2120
+ _gcv, bounds=(0, n), method='Bounded', args=(X, XtWX, wE, XtE, y[:, i])
2121
+ )
2122
+ if est.success:
2123
+ gcv_est[i] = est.x
2124
+ else:
2125
+ raise ValueError(f"Unable to find minimum of the GCV "
2126
+ f"function: {gcv_est.message}")
2127
+ return gcv_est
2128
+ else:
2129
+ # trailing dims must have been flattened already.
2130
+ raise RuntimeError("Internal error. Please report it to scipy developers.")
2131
+
2132
+
2133
+ def _coeff_of_divided_diff(x):
2134
+ """
2135
+ Returns the coefficients of the divided difference.
2136
+
2137
+ Parameters
2138
+ ----------
2139
+ x : array, shape (n,)
2140
+ Array which is used for the computation of divided difference.
2141
+
2142
+ Returns
2143
+ -------
2144
+ res : array_like, shape (n,)
2145
+ Coefficients of the divided difference.
2146
+
2147
+ Notes
2148
+ -----
2149
+ Vector ``x`` should have unique elements, otherwise an error division by
2150
+ zero might be raised.
2151
+
2152
+ No checks are performed.
2153
+
2154
+ """
2155
+ n = x.shape[0]
2156
+ res = np.zeros(n)
2157
+ for i in range(n):
2158
+ pp = 1.
2159
+ for k in range(n):
2160
+ if k != i:
2161
+ pp *= (x[i] - x[k])
2162
+ res[i] = 1. / pp
2163
+ return res
2164
+
2165
+
2166
+ def make_smoothing_spline(x, y, w=None, lam=None, *, axis=0):
2167
+ r"""
2168
+ Create a smoothing B-spline satisfying the Generalized Cross Validation (GCV) criterion.
2169
+
2170
+ Compute the (coefficients of) smoothing cubic spline function using
2171
+ ``lam`` to control the tradeoff between the amount of smoothness of the
2172
+ curve and its proximity to the data. In case ``lam`` is None, using the
2173
+ GCV criteria [1] to find it.
2174
+
2175
+ A smoothing spline is found as a solution to the regularized weighted
2176
+ linear regression problem:
2177
+
2178
+ .. math::
2179
+
2180
+ \sum\limits_{i=1}^n w_i\lvert y_i - f(x_i) \rvert^2 +
2181
+ \lambda\int\limits_{x_1}^{x_n} (f^{(2)}(u))^2 d u
2182
+
2183
+ where :math:`f` is a spline function, :math:`w` is a vector of weights and
2184
+ :math:`\lambda` is a regularization parameter.
2185
+
2186
+ If ``lam`` is None, we use the GCV criteria to find an optimal
2187
+ regularization parameter, otherwise we solve the regularized weighted
2188
+ linear regression problem with given parameter. The parameter controls
2189
+ the tradeoff in the following way: the larger the parameter becomes, the
2190
+ smoother the function gets.
2191
+
2192
+ Parameters
2193
+ ----------
2194
+ x : array_like, shape (n,)
2195
+ Abscissas. `n` must be at least 5.
2196
+ y : array_like, shape (n, ...)
2197
+ Ordinates. `n` must be at least 5.
2198
+ w : array_like, shape (n,), optional
2199
+ Vector of weights. Default is ``np.ones_like(x)``.
2200
+ lam : float, (:math:`\lambda \geq 0`), optional
2201
+ Regularization parameter. If ``lam`` is None, then it is found from
2202
+ the GCV criteria. Default is None.
2203
+ axis : int, optional
2204
+ The data axis. Default is zero.
2205
+ The assumption is that ``y.shape[axis] == n``, and all other axes of ``y``
2206
+ are batching axes.
2207
+
2208
+ Returns
2209
+ -------
2210
+ func : `BSpline` object
2211
+ An object representing a spline in the B-spline basis
2212
+ as a solution of the problem of smoothing splines using
2213
+ the GCV criteria [1] in case ``lam`` is None, otherwise using the
2214
+ given parameter ``lam``.
2215
+
2216
+ Notes
2217
+ -----
2218
+ This algorithm is a clean room reimplementation of the algorithm
2219
+ introduced by Woltring in FORTRAN [2]. The original version cannot be used
2220
+ in SciPy source code because of the license issues. The details of the
2221
+ reimplementation are discussed here (available only in Russian) [4].
2222
+
2223
+ If the vector of weights ``w`` is None, we assume that all the points are
2224
+ equal in terms of weights, and vector of weights is vector of ones.
2225
+
2226
+ Note that in weighted residual sum of squares, weights are not squared:
2227
+ :math:`\sum\limits_{i=1}^n w_i\lvert y_i - f(x_i) \rvert^2` while in
2228
+ ``splrep`` the sum is built from the squared weights.
2229
+
2230
+ In cases when the initial problem is ill-posed (for example, the product
2231
+ :math:`X^T W X` where :math:`X` is a design matrix is not a positive
2232
+ defined matrix) a ValueError is raised.
2233
+
2234
+ References
2235
+ ----------
2236
+ .. [1] G. Wahba, "Estimating the smoothing parameter" in Spline models for
2237
+ observational data, Philadelphia, Pennsylvania: Society for Industrial
2238
+ and Applied Mathematics, 1990, pp. 45-65.
2239
+ :doi:`10.1137/1.9781611970128`
2240
+ .. [2] H. J. Woltring, A Fortran package for generalized, cross-validatory
2241
+ spline smoothing and differentiation, Advances in Engineering
2242
+ Software, vol. 8, no. 2, pp. 104-113, 1986.
2243
+ :doi:`10.1016/0141-1195(86)90098-7`
2244
+ .. [3] T. Hastie, J. Friedman, and R. Tisbshirani, "Smoothing Splines" in
2245
+ The elements of Statistical Learning: Data Mining, Inference, and
2246
+ prediction, New York: Springer, 2017, pp. 241-249.
2247
+ :doi:`10.1007/978-0-387-84858-7`
2248
+ .. [4] E. Zemlyanoy, "Generalized cross-validation smoothing splines",
2249
+ BSc thesis, 2022.
2250
+ `<https://www.hse.ru/ba/am/students/diplomas/620910604>`_ (in
2251
+ Russian)
2252
+
2253
+ Examples
2254
+ --------
2255
+ Generate some noisy data
2256
+
2257
+ >>> import numpy as np
2258
+ >>> np.random.seed(1234)
2259
+ >>> n = 200
2260
+ >>> def func(x):
2261
+ ... return x**3 + x**2 * np.sin(4 * x)
2262
+ >>> x = np.sort(np.random.random_sample(n) * 4 - 2)
2263
+ >>> y = func(x) + np.random.normal(scale=1.5, size=n)
2264
+
2265
+ Make a smoothing spline function
2266
+
2267
+ >>> from scipy.interpolate import make_smoothing_spline
2268
+ >>> spl = make_smoothing_spline(x, y)
2269
+
2270
+ Plot both
2271
+
2272
+ >>> import matplotlib.pyplot as plt
2273
+ >>> grid = np.linspace(x[0], x[-1], 400)
2274
+ >>> plt.plot(x, y, '.')
2275
+ >>> plt.plot(grid, spl(grid), label='Spline')
2276
+ >>> plt.plot(grid, func(grid), label='Original function')
2277
+ >>> plt.legend(loc='best')
2278
+ >>> plt.show()
2279
+
2280
+ """ # noqa:E501
2281
+
2282
+ x = np.ascontiguousarray(x, dtype=float)
2283
+ y = np.ascontiguousarray(y, dtype=float)
2284
+
2285
+ if any(x[1:] - x[:-1] <= 0):
2286
+ raise ValueError('``x`` should be an ascending array')
2287
+
2288
+ if x.ndim != 1 or x.shape[0] != y.shape[axis]:
2289
+ raise ValueError(f'``x`` should be 1D and {x.shape = } == {y.shape = }')
2290
+
2291
+ if w is None:
2292
+ w = np.ones(len(x))
2293
+ else:
2294
+ w = np.ascontiguousarray(w)
2295
+ if any(w <= 0):
2296
+ raise ValueError('Invalid vector of weights')
2297
+
2298
+ t = np.r_[[x[0]] * 3, x, [x[-1]] * 3]
2299
+ n = x.shape[0]
2300
+
2301
+ if n <= 4:
2302
+ raise ValueError('``x`` and ``y`` length must be at least 5')
2303
+
2304
+ # Internals assume that the data axis is the zero-th axis
2305
+ axis = normalize_axis_index(axis, y.ndim)
2306
+ y = np.moveaxis(y, axis, 0)
2307
+
2308
+ # flatten the trailing axes of y to simplify further manipulations
2309
+ y_shape1 = y.shape[1:]
2310
+ if y_shape1 != ():
2311
+ y = y.reshape((n, -1))
2312
+
2313
+ # It is known that the solution to the stated minimization problem exists
2314
+ # and is a natural cubic spline with vector of knots equal to the unique
2315
+ # elements of ``x`` [3], so we will solve the problem in the basis of
2316
+ # natural splines.
2317
+
2318
+ # create design matrix in the B-spline basis
2319
+ X_bspl = BSpline.design_matrix(x, t, 3)
2320
+ # move from B-spline basis to the basis of natural splines using equations
2321
+ # (2.1.7) [4]
2322
+ # central elements
2323
+ X = np.zeros((5, n))
2324
+ for i in range(1, 4):
2325
+ X[i, 2: -2] = X_bspl[i: i - 4, 3: -3][np.diag_indices(n - 4)]
2326
+
2327
+ # first elements
2328
+ X[1, 1] = X_bspl[0, 0]
2329
+ X[2, :2] = ((x[2] + x[1] - 2 * x[0]) * X_bspl[0, 0],
2330
+ X_bspl[1, 1] + X_bspl[1, 2])
2331
+ X[3, :2] = ((x[2] - x[0]) * X_bspl[1, 1], X_bspl[2, 2])
2332
+
2333
+ # last elements
2334
+ X[1, -2:] = (X_bspl[-3, -3], (x[-1] - x[-3]) * X_bspl[-2, -2])
2335
+ X[2, -2:] = (X_bspl[-2, -3] + X_bspl[-2, -2],
2336
+ (2 * x[-1] - x[-2] - x[-3]) * X_bspl[-1, -1])
2337
+ X[3, -2] = X_bspl[-1, -1]
2338
+
2339
+ # create penalty matrix and divide it by vector of weights: W^{-1} E
2340
+ wE = np.zeros((5, n))
2341
+ wE[2:, 0] = _coeff_of_divided_diff(x[:3]) / w[:3]
2342
+ wE[1:, 1] = _coeff_of_divided_diff(x[:4]) / w[:4]
2343
+ for j in range(2, n - 2):
2344
+ wE[:, j] = (x[j+2] - x[j-2]) * _coeff_of_divided_diff(x[j-2:j+3])\
2345
+ / w[j-2: j+3]
2346
+
2347
+ wE[:-1, -2] = -_coeff_of_divided_diff(x[-4:]) / w[-4:]
2348
+ wE[:-2, -1] = _coeff_of_divided_diff(x[-3:]) / w[-3:]
2349
+ wE *= 6
2350
+
2351
+ if lam is None:
2352
+ lam = _compute_optimal_gcv_parameter(X, wE, y, w)
2353
+ elif lam < 0.:
2354
+ raise ValueError('Regularization parameter should be non-negative')
2355
+
2356
+ # solve the initial problem in the basis of natural splines
2357
+ if np.ndim(lam) == 0:
2358
+ c = solve_banded((2, 2), X + lam * wE, y)
2359
+ elif np.ndim(lam) == 1:
2360
+ # XXX: solve_banded does not suppport batched `ab` matrices; loop manually
2361
+ c = np.empty((n, lam.shape[0]))
2362
+ for i in range(lam.shape[0]):
2363
+ c[:, i] = solve_banded((2, 2), X + lam[i] * wE, y[:, i])
2364
+ else:
2365
+ # this should not happen, ever
2366
+ raise RuntimeError("Internal error, please report it to SciPy developers.")
2367
+ c = c.reshape((c.shape[0], *y_shape1))
2368
+
2369
+ # hack: these are c[0], c[1] etc, shape-compatible with np.r_ below
2370
+ c0, c1 = c[0:1, ...], c[1:2, ...] # c[0], c[1]
2371
+ cm0, cm1 = c[-1:-2:-1, ...], c[-2:-3:-1, ...] # c[-1], c[-2]
2372
+
2373
+ # move back to B-spline basis using equations (2.2.10) [4]
2374
+ c_ = np.r_[c0 * (t[5] + t[4] - 2 * t[3]) + c1,
2375
+ c0 * (t[5] - t[3]) + c1,
2376
+ c[1: -1, ...],
2377
+ cm0 * (t[-4] - t[-6]) + cm1,
2378
+ cm0 * (2 * t[-4] - t[-5] - t[-6]) + cm1]
2379
+
2380
+ return BSpline.construct_fast(t, c_, 3, axis=axis)
2381
+
2382
+
2383
+ ########################
2384
+ # FITPACK look-alikes #
2385
+ ########################
2386
+
2387
+ def fpcheck(x, t, k):
2388
+ """ Check consistency of the data vector `x` and the knot vector `t`.
2389
+
2390
+ Return None if inputs are consistent, raises a ValueError otherwise.
2391
+ """
2392
+ # This routine is a clone of the `fpchec` Fortran routine,
2393
+ # https://github.com/scipy/scipy/blob/main/scipy/interpolate/fitpack/fpchec.f
2394
+ # which carries the following comment:
2395
+ #
2396
+ # subroutine fpchec verifies the number and the position of the knots
2397
+ # t(j),j=1,2,...,n of a spline of degree k, in relation to the number
2398
+ # and the position of the data points x(i),i=1,2,...,m. if all of the
2399
+ # following conditions are fulfilled, the error parameter ier is set
2400
+ # to zero. if one of the conditions is violated ier is set to ten.
2401
+ # 1) k+1 <= n-k-1 <= m
2402
+ # 2) t(1) <= t(2) <= ... <= t(k+1)
2403
+ # t(n-k) <= t(n-k+1) <= ... <= t(n)
2404
+ # 3) t(k+1) < t(k+2) < ... < t(n-k)
2405
+ # 4) t(k+1) <= x(i) <= t(n-k)
2406
+ # 5) the conditions specified by schoenberg and whitney must hold
2407
+ # for at least one subset of data points, i.e. there must be a
2408
+ # subset of data points y(j) such that
2409
+ # t(j) < y(j) < t(j+k+1), j=1,2,...,n-k-1
2410
+ x = np.asarray(x)
2411
+ t = np.asarray(t)
2412
+
2413
+ if x.ndim != 1 or t.ndim != 1:
2414
+ raise ValueError(f"Expect `x` and `t` be 1D sequences. Got {x = } and {t = }")
2415
+
2416
+ m = x.shape[0]
2417
+ n = t.shape[0]
2418
+ nk1 = n - k - 1
2419
+
2420
+ # check condition no 1
2421
+ # c 1) k+1 <= n-k-1 <= m
2422
+ if not (k + 1 <= nk1 <= m):
2423
+ raise ValueError(f"Need k+1 <= n-k-1 <= m. Got {m = }, {n = } and {k = }.")
2424
+
2425
+ # check condition no 2
2426
+ # c 2) t(1) <= t(2) <= ... <= t(k+1)
2427
+ # c t(n-k) <= t(n-k+1) <= ... <= t(n)
2428
+ if (t[:k+1] > t[1:k+2]).any():
2429
+ raise ValueError(f"First k knots must be ordered; got {t = }.")
2430
+
2431
+ if (t[nk1:] < t[nk1-1:-1]).any():
2432
+ raise ValueError(f"Last k knots must be ordered; got {t = }.")
2433
+
2434
+ # c check condition no 3
2435
+ # c 3) t(k+1) < t(k+2) < ... < t(n-k)
2436
+ if (t[k+1:n-k] <= t[k:n-k-1]).any():
2437
+ raise ValueError(f"Internal knots must be distinct. Got {t = }.")
2438
+
2439
+ # c check condition no 4
2440
+ # c 4) t(k+1) <= x(i) <= t(n-k)
2441
+ # NB: FITPACK's fpchec only checks x[0] & x[-1], so we follow.
2442
+ if (x[0] < t[k]) or (x[-1] > t[n-k-1]):
2443
+ raise ValueError(f"Out of bounds: {x = } and {t = }.")
2444
+
2445
+ # c check condition no 5
2446
+ # c 5) the conditions specified by schoenberg and whitney must hold
2447
+ # c for at least one subset of data points, i.e. there must be a
2448
+ # c subset of data points y(j) such that
2449
+ # c t(j) < y(j) < t(j+k+1), j=1,2,...,n-k-1
2450
+ mesg = f"Schoenberg-Whitney condition is violated with {t = } and {x =}."
2451
+
2452
+ if (x[0] >= t[k+1]) or (x[-1] <= t[n-k-2]):
2453
+ raise ValueError(mesg)
2454
+
2455
+ m = x.shape[0]
2456
+ l = k+1
2457
+ nk3 = n - k - 3
2458
+ if nk3 < 2:
2459
+ return
2460
+ for j in range(1, nk3+1):
2461
+ tj = t[j]
2462
+ l += 1
2463
+ tl = t[l]
2464
+ i = np.argmax(x > tj)
2465
+ if i >= m-1:
2466
+ raise ValueError(mesg)
2467
+ if x[i] >= tl:
2468
+ raise ValueError(mesg)
2469
+ return