scipy 1.15.2__cp312-cp312-macosx_14_0_arm64.whl → 1.16.0__cp312-cp312-macosx_14_0_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 (642) hide show
  1. scipy/.dylibs/libgcc_s.1.1.dylib +0 -0
  2. scipy/.dylibs/libgfortran.5.dylib +0 -0
  3. scipy/.dylibs/libquadmath.0.dylib +0 -0
  4. scipy/__config__.py +5 -5
  5. scipy/__init__.py +3 -6
  6. scipy/_cyutility.cpython-312-darwin.so +0 -0
  7. scipy/_lib/_array_api.py +497 -161
  8. scipy/_lib/_array_api_compat_vendor.py +9 -0
  9. scipy/_lib/_bunch.py +4 -0
  10. scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
  11. scipy/_lib/_docscrape.py +1 -1
  12. scipy/_lib/_elementwise_iterative_method.py +15 -26
  13. scipy/_lib/_sparse.py +41 -0
  14. scipy/_lib/_test_ccallback.cpython-312-darwin.so +0 -0
  15. scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
  16. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  17. scipy/_lib/_testutils.py +6 -2
  18. scipy/_lib/_util.py +222 -125
  19. scipy/_lib/array_api_compat/__init__.py +4 -4
  20. scipy/_lib/array_api_compat/_internal.py +19 -6
  21. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  22. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  23. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  24. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  25. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  26. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  27. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  28. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  29. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  30. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  31. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  32. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  33. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  34. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  35. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  36. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  37. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  38. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  39. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  40. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  41. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  42. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  43. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  44. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  45. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  46. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  47. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  48. scipy/_lib/array_api_extra/__init__.py +26 -3
  49. scipy/_lib/array_api_extra/_delegation.py +171 -0
  50. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  51. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  52. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  53. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  54. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  55. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  59. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  60. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  61. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  62. scipy/_lib/array_api_extra/testing.py +359 -0
  63. scipy/_lib/decorator.py +2 -2
  64. scipy/_lib/doccer.py +1 -7
  65. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  66. scipy/_lib/pyprima/__init__.py +212 -0
  67. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  68. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  69. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  70. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  71. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  72. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  73. scipy/_lib/pyprima/cobyla/update.py +289 -0
  74. scipy/_lib/pyprima/common/__init__.py +0 -0
  75. scipy/_lib/pyprima/common/_bounds.py +34 -0
  76. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  77. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  78. scipy/_lib/pyprima/common/_project.py +173 -0
  79. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  80. scipy/_lib/pyprima/common/consts.py +47 -0
  81. scipy/_lib/pyprima/common/evaluate.py +99 -0
  82. scipy/_lib/pyprima/common/history.py +38 -0
  83. scipy/_lib/pyprima/common/infos.py +30 -0
  84. scipy/_lib/pyprima/common/linalg.py +435 -0
  85. scipy/_lib/pyprima/common/message.py +290 -0
  86. scipy/_lib/pyprima/common/powalg.py +131 -0
  87. scipy/_lib/pyprima/common/preproc.py +277 -0
  88. scipy/_lib/pyprima/common/present.py +5 -0
  89. scipy/_lib/pyprima/common/ratio.py +54 -0
  90. scipy/_lib/pyprima/common/redrho.py +47 -0
  91. scipy/_lib/pyprima/common/selectx.py +296 -0
  92. scipy/_lib/tests/test__util.py +105 -121
  93. scipy/_lib/tests/test_array_api.py +169 -34
  94. scipy/_lib/tests/test_bunch.py +7 -0
  95. scipy/_lib/tests/test_ccallback.py +2 -10
  96. scipy/_lib/tests/test_public_api.py +13 -0
  97. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  98. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  99. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  100. scipy/cluster/hierarchy.py +393 -223
  101. scipy/cluster/tests/test_hierarchy.py +273 -335
  102. scipy/cluster/tests/test_vq.py +45 -61
  103. scipy/cluster/vq.py +39 -35
  104. scipy/conftest.py +282 -151
  105. scipy/constants/_constants.py +4 -1
  106. scipy/constants/tests/test_codata.py +2 -2
  107. scipy/constants/tests/test_constants.py +11 -18
  108. scipy/datasets/_download_all.py +15 -1
  109. scipy/datasets/_fetchers.py +7 -1
  110. scipy/datasets/_utils.py +1 -1
  111. scipy/differentiate/_differentiate.py +25 -25
  112. scipy/differentiate/tests/test_differentiate.py +24 -25
  113. scipy/fft/_basic.py +20 -0
  114. scipy/fft/_helper.py +3 -34
  115. scipy/fft/_pocketfft/helper.py +29 -1
  116. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  117. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  118. scipy/fft/_realtransforms.py +13 -0
  119. scipy/fft/tests/test_basic.py +27 -25
  120. scipy/fft/tests/test_fftlog.py +16 -7
  121. scipy/fft/tests/test_helper.py +18 -34
  122. scipy/fft/tests/test_real_transforms.py +8 -10
  123. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  124. scipy/fftpack/tests/test_basic.py +2 -4
  125. scipy/fftpack/tests/test_real_transforms.py +8 -9
  126. scipy/integrate/_bvp.py +9 -3
  127. scipy/integrate/_cubature.py +3 -2
  128. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  129. scipy/integrate/_ivp/common.py +3 -3
  130. scipy/integrate/_ivp/ivp.py +9 -2
  131. scipy/integrate/_ivp/tests/test_ivp.py +19 -0
  132. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  133. scipy/integrate/_ode.py +9 -2
  134. scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
  135. scipy/integrate/_quad_vec.py +21 -29
  136. scipy/integrate/_quadpack.cpython-312-darwin.so +0 -0
  137. scipy/integrate/_quadpack_py.py +11 -7
  138. scipy/integrate/_quadrature.py +3 -3
  139. scipy/integrate/_rules/_base.py +2 -2
  140. scipy/integrate/_tanhsinh.py +57 -54
  141. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  142. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  143. scipy/integrate/tests/test__quad_vec.py +0 -6
  144. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  145. scipy/integrate/tests/test_cubature.py +21 -35
  146. scipy/integrate/tests/test_quadrature.py +6 -8
  147. scipy/integrate/tests/test_tanhsinh.py +61 -43
  148. scipy/interpolate/__init__.py +70 -58
  149. scipy/interpolate/_bary_rational.py +22 -22
  150. scipy/interpolate/_bsplines.py +119 -66
  151. scipy/interpolate/_cubic.py +65 -50
  152. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  153. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  154. scipy/interpolate/_fitpack.cpython-312-darwin.so +0 -0
  155. scipy/interpolate/_fitpack2.py +9 -6
  156. scipy/interpolate/_fitpack_impl.py +32 -26
  157. scipy/interpolate/_fitpack_repro.py +23 -19
  158. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  159. scipy/interpolate/_interpolate.py +30 -12
  160. scipy/interpolate/_ndbspline.py +13 -18
  161. scipy/interpolate/_ndgriddata.py +5 -8
  162. scipy/interpolate/_polyint.py +95 -31
  163. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  164. scipy/interpolate/_rbf.py +2 -2
  165. scipy/interpolate/_rbfinterp.py +1 -1
  166. scipy/interpolate/_rbfinterp_pythran.cpython-312-darwin.so +0 -0
  167. scipy/interpolate/_rgi.py +31 -26
  168. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  169. scipy/interpolate/dfitpack.py +0 -20
  170. scipy/interpolate/interpnd.py +1 -2
  171. scipy/interpolate/tests/test_bary_rational.py +2 -2
  172. scipy/interpolate/tests/test_bsplines.py +97 -1
  173. scipy/interpolate/tests/test_fitpack2.py +39 -1
  174. scipy/interpolate/tests/test_interpnd.py +32 -20
  175. scipy/interpolate/tests/test_interpolate.py +48 -4
  176. scipy/interpolate/tests/test_rgi.py +2 -1
  177. scipy/io/_fast_matrix_market/__init__.py +2 -0
  178. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  179. scipy/io/_harwell_boeing/hb.py +7 -11
  180. scipy/io/_idl.py +5 -7
  181. scipy/io/_netcdf.py +15 -5
  182. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  183. scipy/io/arff/tests/test_arffread.py +3 -3
  184. scipy/io/matlab/__init__.py +5 -3
  185. scipy/io/matlab/_mio.py +4 -1
  186. scipy/io/matlab/_mio5.py +19 -13
  187. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  188. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  189. scipy/io/matlab/_miobase.py +4 -1
  190. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  191. scipy/io/matlab/tests/test_mio.py +46 -18
  192. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  193. scipy/io/tests/test_mmio.py +7 -1
  194. scipy/io/tests/test_wavfile.py +41 -0
  195. scipy/io/wavfile.py +57 -10
  196. scipy/linalg/_basic.py +113 -86
  197. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  198. scipy/linalg/_decomp.py +22 -9
  199. scipy/linalg/_decomp_cholesky.py +28 -13
  200. scipy/linalg/_decomp_cossin.py +45 -30
  201. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  202. scipy/linalg/_decomp_ldl.py +4 -1
  203. scipy/linalg/_decomp_lu.py +18 -6
  204. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  205. scipy/linalg/_decomp_polar.py +2 -0
  206. scipy/linalg/_decomp_qr.py +6 -2
  207. scipy/linalg/_decomp_qz.py +3 -0
  208. scipy/linalg/_decomp_schur.py +3 -1
  209. scipy/linalg/_decomp_svd.py +13 -2
  210. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  211. scipy/linalg/_expm_frechet.py +4 -0
  212. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  213. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  214. scipy/linalg/_linalg_pythran.cpython-312-darwin.so +0 -0
  215. scipy/linalg/_matfuncs.py +187 -4
  216. scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
  217. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  218. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  219. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  220. scipy/linalg/_procrustes.py +2 -0
  221. scipy/linalg/_sketches.py +17 -6
  222. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  223. scipy/linalg/_solvers.py +7 -2
  224. scipy/linalg/_special_matrices.py +26 -36
  225. scipy/linalg/blas.py +35 -24
  226. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  227. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  228. scipy/linalg/lapack.py +22 -2
  229. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  230. scipy/linalg/tests/test_basic.py +31 -16
  231. scipy/linalg/tests/test_batch.py +588 -0
  232. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  233. scipy/linalg/tests/test_decomp.py +40 -3
  234. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  235. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  236. scipy/linalg/tests/test_interpolative.py +17 -0
  237. scipy/linalg/tests/test_lapack.py +115 -7
  238. scipy/linalg/tests/test_matfuncs.py +157 -102
  239. scipy/linalg/tests/test_procrustes.py +0 -7
  240. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  241. scipy/linalg/tests/test_special_matrices.py +1 -5
  242. scipy/ndimage/__init__.py +1 -0
  243. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  244. scipy/ndimage/_delegators.py +8 -2
  245. scipy/ndimage/_filters.py +453 -5
  246. scipy/ndimage/_interpolation.py +36 -6
  247. scipy/ndimage/_measurements.py +4 -2
  248. scipy/ndimage/_morphology.py +5 -0
  249. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  250. scipy/ndimage/_ndimage_api.py +2 -1
  251. scipy/ndimage/_ni_docstrings.py +5 -1
  252. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  253. scipy/ndimage/_ni_support.py +1 -5
  254. scipy/ndimage/_rank_filter_1d.cpython-312-darwin.so +0 -0
  255. scipy/ndimage/_support_alternative_backends.py +18 -6
  256. scipy/ndimage/tests/test_filters.py +384 -259
  257. scipy/ndimage/tests/test_fourier.py +7 -9
  258. scipy/ndimage/tests/test_interpolation.py +68 -61
  259. scipy/ndimage/tests/test_measurements.py +18 -35
  260. scipy/ndimage/tests/test_morphology.py +143 -131
  261. scipy/ndimage/tests/test_splines.py +1 -3
  262. scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
  263. scipy/optimize/_basinhopping.py +13 -7
  264. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  265. scipy/optimize/_bracket.py +46 -26
  266. scipy/optimize/_chandrupatla.py +9 -10
  267. scipy/optimize/_cobyla_py.py +104 -123
  268. scipy/optimize/_constraints.py +14 -10
  269. scipy/optimize/_differentiable_functions.py +371 -230
  270. scipy/optimize/_differentialevolution.py +4 -3
  271. scipy/optimize/_direct.cpython-312-darwin.so +0 -0
  272. scipy/optimize/_dual_annealing.py +1 -1
  273. scipy/optimize/_elementwise.py +1 -4
  274. scipy/optimize/_group_columns.cpython-312-darwin.so +0 -0
  275. scipy/optimize/_highspy/_highs_wrapper.py +6 -4
  276. scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
  277. scipy/optimize/_lbfgsb_py.py +80 -24
  278. scipy/optimize/_linprog_doc.py +2 -2
  279. scipy/optimize/_linprog_highs.py +11 -11
  280. scipy/optimize/_linprog_ip.py +25 -10
  281. scipy/optimize/_linprog_util.py +18 -19
  282. scipy/optimize/_lsap.cpython-312-darwin.so +0 -0
  283. scipy/optimize/_lsq/common.py +3 -3
  284. scipy/optimize/_lsq/dogbox.py +16 -2
  285. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  286. scipy/optimize/_lsq/least_squares.py +198 -126
  287. scipy/optimize/_lsq/lsq_linear.py +6 -6
  288. scipy/optimize/_lsq/trf.py +35 -8
  289. scipy/optimize/_milp.py +3 -1
  290. scipy/optimize/_minimize.py +105 -36
  291. scipy/optimize/_minpack.cpython-312-darwin.so +0 -0
  292. scipy/optimize/_minpack_py.py +21 -14
  293. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  294. scipy/optimize/_nnls.py +20 -21
  295. scipy/optimize/_nonlin.py +34 -3
  296. scipy/optimize/_numdiff.py +288 -110
  297. scipy/optimize/_optimize.py +86 -48
  298. scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
  299. scipy/optimize/_remove_redundancy.py +5 -5
  300. scipy/optimize/_root_scalar.py +1 -1
  301. scipy/optimize/_shgo.py +6 -0
  302. scipy/optimize/_shgo_lib/_complex.py +1 -1
  303. scipy/optimize/_slsqp_py.py +216 -124
  304. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  305. scipy/optimize/_spectral.py +1 -1
  306. scipy/optimize/_tnc.py +8 -1
  307. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  308. scipy/optimize/_trustregion.py +20 -6
  309. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  310. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  311. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  312. scipy/optimize/_trustregion_constr/projections.py +12 -8
  313. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  314. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  315. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  316. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  317. scipy/optimize/_trustregion_exact.py +0 -1
  318. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  319. scipy/optimize/_zeros_py.py +97 -17
  320. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  321. scipy/optimize/slsqp.py +0 -1
  322. scipy/optimize/tests/test__basinhopping.py +1 -1
  323. scipy/optimize/tests/test__differential_evolution.py +4 -4
  324. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  325. scipy/optimize/tests/test__numdiff.py +66 -22
  326. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  327. scipy/optimize/tests/test__shgo.py +9 -1
  328. scipy/optimize/tests/test_bracket.py +71 -46
  329. scipy/optimize/tests/test_chandrupatla.py +133 -135
  330. scipy/optimize/tests/test_cobyla.py +74 -45
  331. scipy/optimize/tests/test_constraints.py +1 -1
  332. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  333. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  334. scipy/optimize/tests/test_least_squares.py +125 -13
  335. scipy/optimize/tests/test_linear_assignment.py +3 -3
  336. scipy/optimize/tests/test_linprog.py +3 -3
  337. scipy/optimize/tests/test_lsq_linear.py +6 -6
  338. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  339. scipy/optimize/tests/test_minpack.py +4 -4
  340. scipy/optimize/tests/test_nnls.py +43 -3
  341. scipy/optimize/tests/test_nonlin.py +36 -0
  342. scipy/optimize/tests/test_optimize.py +98 -20
  343. scipy/optimize/tests/test_slsqp.py +36 -4
  344. scipy/optimize/tests/test_zeros.py +34 -1
  345. scipy/signal/__init__.py +12 -23
  346. scipy/signal/_delegators.py +568 -0
  347. scipy/signal/_filter_design.py +459 -241
  348. scipy/signal/_fir_filter_design.py +262 -90
  349. scipy/signal/_lti_conversion.py +3 -2
  350. scipy/signal/_ltisys.py +118 -91
  351. scipy/signal/_max_len_seq_inner.cpython-312-darwin.so +0 -0
  352. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  353. scipy/signal/_polyutils.py +172 -0
  354. scipy/signal/_short_time_fft.py +553 -76
  355. scipy/signal/_signal_api.py +30 -0
  356. scipy/signal/_signaltools.py +719 -396
  357. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  358. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  359. scipy/signal/_spectral_py.py +230 -50
  360. scipy/signal/_spline.cpython-312-darwin.so +0 -0
  361. scipy/signal/_spline_filters.py +108 -68
  362. scipy/signal/_support_alternative_backends.py +73 -0
  363. scipy/signal/_upfirdn.py +4 -1
  364. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  365. scipy/signal/_waveforms.py +2 -11
  366. scipy/signal/_wavelets.py +1 -1
  367. scipy/signal/fir_filter_design.py +1 -0
  368. scipy/signal/spline.py +4 -11
  369. scipy/signal/tests/_scipy_spectral_test_shim.py +5 -182
  370. scipy/signal/tests/test_bsplines.py +114 -79
  371. scipy/signal/tests/test_cont2discrete.py +9 -2
  372. scipy/signal/tests/test_filter_design.py +721 -481
  373. scipy/signal/tests/test_fir_filter_design.py +332 -140
  374. scipy/signal/tests/test_savitzky_golay.py +4 -3
  375. scipy/signal/tests/test_short_time_fft.py +231 -5
  376. scipy/signal/tests/test_signaltools.py +2150 -1349
  377. scipy/signal/tests/test_spectral.py +50 -6
  378. scipy/signal/tests/test_splines.py +161 -96
  379. scipy/signal/tests/test_upfirdn.py +84 -50
  380. scipy/signal/tests/test_waveforms.py +20 -0
  381. scipy/signal/tests/test_windows.py +607 -466
  382. scipy/signal/windows/_windows.py +287 -148
  383. scipy/sparse/__init__.py +23 -4
  384. scipy/sparse/_base.py +269 -120
  385. scipy/sparse/_bsr.py +7 -4
  386. scipy/sparse/_compressed.py +59 -234
  387. scipy/sparse/_construct.py +90 -38
  388. scipy/sparse/_coo.py +115 -181
  389. scipy/sparse/_csc.py +4 -4
  390. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  391. scipy/sparse/_csr.py +2 -2
  392. scipy/sparse/_data.py +48 -48
  393. scipy/sparse/_dia.py +105 -21
  394. scipy/sparse/_dok.py +0 -23
  395. scipy/sparse/_index.py +4 -4
  396. scipy/sparse/_matrix.py +23 -0
  397. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  398. scipy/sparse/_sputils.py +37 -22
  399. scipy/sparse/base.py +0 -9
  400. scipy/sparse/bsr.py +0 -14
  401. scipy/sparse/compressed.py +0 -23
  402. scipy/sparse/construct.py +0 -6
  403. scipy/sparse/coo.py +0 -14
  404. scipy/sparse/csc.py +0 -3
  405. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  406. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  407. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  408. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  409. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  410. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  411. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  412. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  413. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  414. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  415. scipy/sparse/csr.py +0 -5
  416. scipy/sparse/data.py +1 -6
  417. scipy/sparse/dia.py +0 -7
  418. scipy/sparse/dok.py +0 -10
  419. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  420. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  421. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  422. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  423. scipy/sparse/linalg/_eigen/arpack/arpack.py +28 -20
  424. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  425. scipy/sparse/linalg/_expm_multiply.py +8 -3
  426. scipy/sparse/linalg/_interface.py +29 -26
  427. scipy/sparse/linalg/_isolve/_gcrotmk.py +6 -5
  428. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  429. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  430. scipy/sparse/linalg/_isolve/minres.py +5 -5
  431. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  432. scipy/sparse/linalg/_isolve/utils.py +2 -8
  433. scipy/sparse/linalg/_matfuncs.py +1 -1
  434. scipy/sparse/linalg/_norm.py +1 -1
  435. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  436. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  437. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  438. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  439. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  440. scipy/sparse/linalg/tests/test_expm_multiply.py +10 -0
  441. scipy/sparse/linalg/tests/test_interface.py +35 -0
  442. scipy/sparse/linalg/tests/test_pydata_sparse.py +18 -0
  443. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  444. scipy/sparse/tests/test_base.py +224 -40
  445. scipy/sparse/tests/test_common1d.py +17 -12
  446. scipy/sparse/tests/test_construct.py +1 -1
  447. scipy/sparse/tests/test_coo.py +272 -4
  448. scipy/sparse/tests/test_sparsetools.py +5 -0
  449. scipy/sparse/tests/test_sputils.py +36 -7
  450. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  451. scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
  452. scipy/spatial/_distance_wrap.cpython-312-darwin.so +0 -0
  453. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  454. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  455. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  456. scipy/spatial/distance.py +49 -42
  457. scipy/spatial/tests/test_distance.py +15 -1
  458. scipy/spatial/tests/test_kdtree.py +1 -0
  459. scipy/spatial/tests/test_qhull.py +106 -2
  460. scipy/spatial/transform/__init__.py +5 -3
  461. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  462. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  463. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  464. scipy/spatial/transform/tests/test_rotation.py +1342 -790
  465. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  466. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  467. scipy/special/__init__.py +1 -47
  468. scipy/special/_add_newdocs.py +34 -772
  469. scipy/special/_basic.py +22 -25
  470. scipy/special/_comb.cpython-312-darwin.so +0 -0
  471. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  472. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  473. scipy/special/_logsumexp.py +83 -69
  474. scipy/special/_orthogonal.pyi +1 -1
  475. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  476. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  477. scipy/special/_spherical_bessel.py +4 -4
  478. scipy/special/_support_alternative_backends.py +212 -119
  479. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  480. scipy/special/_testutils.py +4 -4
  481. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  482. scipy/special/_ufuncs.pyi +1 -0
  483. scipy/special/_ufuncs.pyx +215 -1400
  484. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  485. scipy/special/_ufuncs_cxx.pxd +2 -15
  486. scipy/special/_ufuncs_cxx.pyx +5 -44
  487. scipy/special/_ufuncs_cxx_defs.h +2 -16
  488. scipy/special/_ufuncs_defs.h +0 -8
  489. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  490. scipy/special/cython_special.pxd +1 -1
  491. scipy/special/tests/_cython_examples/meson.build +10 -1
  492. scipy/special/tests/test_basic.py +153 -20
  493. scipy/special/tests/test_boost_ufuncs.py +3 -0
  494. scipy/special/tests/test_cdflib.py +35 -11
  495. scipy/special/tests/test_gammainc.py +16 -0
  496. scipy/special/tests/test_hyp2f1.py +23 -2
  497. scipy/special/tests/test_log1mexp.py +85 -0
  498. scipy/special/tests/test_logsumexp.py +220 -64
  499. scipy/special/tests/test_mpmath.py +1 -0
  500. scipy/special/tests/test_nan_inputs.py +1 -1
  501. scipy/special/tests/test_orthogonal.py +17 -18
  502. scipy/special/tests/test_sf_error.py +3 -2
  503. scipy/special/tests/test_sph_harm.py +6 -7
  504. scipy/special/tests/test_support_alternative_backends.py +211 -76
  505. scipy/stats/__init__.py +4 -1
  506. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  507. scipy/stats/_axis_nan_policy.py +5 -12
  508. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  509. scipy/stats/_continued_fraction.py +387 -0
  510. scipy/stats/_continuous_distns.py +296 -319
  511. scipy/stats/_correlation.py +1 -1
  512. scipy/stats/_covariance.py +6 -3
  513. scipy/stats/_discrete_distns.py +39 -32
  514. scipy/stats/_distn_infrastructure.py +39 -12
  515. scipy/stats/_distribution_infrastructure.py +920 -238
  516. scipy/stats/_entropy.py +9 -10
  517. scipy/{_lib → stats}/_finite_differences.py +1 -1
  518. scipy/stats/_hypotests.py +83 -50
  519. scipy/stats/_kde.py +53 -49
  520. scipy/stats/_ksstats.py +1 -1
  521. scipy/stats/_levy_stable/__init__.py +7 -15
  522. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  523. scipy/stats/_morestats.py +118 -73
  524. scipy/stats/_mstats_basic.py +13 -17
  525. scipy/stats/_mstats_extras.py +8 -8
  526. scipy/stats/_multivariate.py +89 -113
  527. scipy/stats/_new_distributions.py +97 -20
  528. scipy/stats/_page_trend_test.py +12 -5
  529. scipy/stats/_probability_distribution.py +265 -43
  530. scipy/stats/_qmc.py +14 -9
  531. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  532. scipy/stats/_qmvnt.py +16 -95
  533. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  534. scipy/stats/_quantile.py +335 -0
  535. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  536. scipy/stats/_resampling.py +5 -30
  537. scipy/stats/_sampling.py +1 -1
  538. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  539. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  540. scipy/stats/_stats_mstats_common.py +21 -2
  541. scipy/stats/_stats_py.py +551 -477
  542. scipy/stats/_stats_pythran.cpython-312-darwin.so +0 -0
  543. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  544. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  545. scipy/stats/_variation.py +6 -8
  546. scipy/stats/_wilcoxon.py +13 -7
  547. scipy/stats/tests/common_tests.py +6 -4
  548. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  549. scipy/stats/tests/test_continued_fraction.py +173 -0
  550. scipy/stats/tests/test_continuous.py +379 -60
  551. scipy/stats/tests/test_continuous_basic.py +18 -12
  552. scipy/stats/tests/test_discrete_basic.py +14 -8
  553. scipy/stats/tests/test_discrete_distns.py +16 -16
  554. scipy/stats/tests/test_distributions.py +117 -75
  555. scipy/stats/tests/test_entropy.py +40 -48
  556. scipy/stats/tests/test_fit.py +4 -3
  557. scipy/stats/tests/test_hypotests.py +153 -24
  558. scipy/stats/tests/test_kdeoth.py +109 -41
  559. scipy/stats/tests/test_marray.py +289 -0
  560. scipy/stats/tests/test_morestats.py +81 -49
  561. scipy/stats/tests/test_mstats_basic.py +3 -3
  562. scipy/stats/tests/test_multivariate.py +434 -83
  563. scipy/stats/tests/test_qmc.py +13 -10
  564. scipy/stats/tests/test_quantile.py +199 -0
  565. scipy/stats/tests/test_rank.py +119 -112
  566. scipy/stats/tests/test_resampling.py +47 -56
  567. scipy/stats/tests/test_sampling.py +9 -4
  568. scipy/stats/tests/test_stats.py +799 -939
  569. scipy/stats/tests/test_variation.py +8 -6
  570. scipy/version.py +2 -2
  571. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/LICENSE.txt +4 -4
  572. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/METADATA +12 -12
  573. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/RECORD +574 -581
  574. scipy-1.16.0.dist-info/WHEEL +6 -0
  575. scipy/_lib/array_api_extra/_funcs.py +0 -484
  576. scipy/_lib/array_api_extra/_typing.py +0 -8
  577. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  578. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  579. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  580. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  581. scipy/spatial/qhull_src/COPYING.txt +0 -38
  582. scipy/special/libsf_error_state.dylib +0 -0
  583. scipy/special/tests/test_log_softmax.py +0 -109
  584. scipy/special/tests/test_xsf_cuda.py +0 -114
  585. scipy/special/xsf/binom.h +0 -89
  586. scipy/special/xsf/cdflib.h +0 -100
  587. scipy/special/xsf/cephes/airy.h +0 -307
  588. scipy/special/xsf/cephes/besselpoly.h +0 -51
  589. scipy/special/xsf/cephes/beta.h +0 -257
  590. scipy/special/xsf/cephes/cbrt.h +0 -131
  591. scipy/special/xsf/cephes/chbevl.h +0 -85
  592. scipy/special/xsf/cephes/chdtr.h +0 -193
  593. scipy/special/xsf/cephes/const.h +0 -87
  594. scipy/special/xsf/cephes/ellie.h +0 -293
  595. scipy/special/xsf/cephes/ellik.h +0 -251
  596. scipy/special/xsf/cephes/ellpe.h +0 -107
  597. scipy/special/xsf/cephes/ellpk.h +0 -117
  598. scipy/special/xsf/cephes/expn.h +0 -260
  599. scipy/special/xsf/cephes/gamma.h +0 -398
  600. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  601. scipy/special/xsf/cephes/hyperg.h +0 -361
  602. scipy/special/xsf/cephes/i0.h +0 -149
  603. scipy/special/xsf/cephes/i1.h +0 -158
  604. scipy/special/xsf/cephes/igam.h +0 -421
  605. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  606. scipy/special/xsf/cephes/igami.h +0 -313
  607. scipy/special/xsf/cephes/j0.h +0 -225
  608. scipy/special/xsf/cephes/j1.h +0 -198
  609. scipy/special/xsf/cephes/jv.h +0 -715
  610. scipy/special/xsf/cephes/k0.h +0 -164
  611. scipy/special/xsf/cephes/k1.h +0 -163
  612. scipy/special/xsf/cephes/kn.h +0 -243
  613. scipy/special/xsf/cephes/lanczos.h +0 -112
  614. scipy/special/xsf/cephes/ndtr.h +0 -275
  615. scipy/special/xsf/cephes/poch.h +0 -85
  616. scipy/special/xsf/cephes/polevl.h +0 -167
  617. scipy/special/xsf/cephes/psi.h +0 -194
  618. scipy/special/xsf/cephes/rgamma.h +0 -111
  619. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  620. scipy/special/xsf/cephes/shichi.h +0 -248
  621. scipy/special/xsf/cephes/sici.h +0 -224
  622. scipy/special/xsf/cephes/sindg.h +0 -221
  623. scipy/special/xsf/cephes/tandg.h +0 -139
  624. scipy/special/xsf/cephes/trig.h +0 -58
  625. scipy/special/xsf/cephes/unity.h +0 -186
  626. scipy/special/xsf/cephes/zeta.h +0 -172
  627. scipy/special/xsf/config.h +0 -304
  628. scipy/special/xsf/digamma.h +0 -205
  629. scipy/special/xsf/error.h +0 -57
  630. scipy/special/xsf/evalpoly.h +0 -47
  631. scipy/special/xsf/expint.h +0 -266
  632. scipy/special/xsf/hyp2f1.h +0 -694
  633. scipy/special/xsf/iv_ratio.h +0 -173
  634. scipy/special/xsf/lambertw.h +0 -150
  635. scipy/special/xsf/loggamma.h +0 -163
  636. scipy/special/xsf/sici.h +0 -200
  637. scipy/special/xsf/tools.h +0 -427
  638. scipy/special/xsf/trig.h +0 -164
  639. scipy/special/xsf/wright_bessel.h +0 -843
  640. scipy/special/xsf/zlog1.h +0 -35
  641. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  642. scipy-1.15.2.dist-info/WHEEL +0 -4
@@ -6,6 +6,7 @@ import warnings
6
6
  from collections.abc import Iterable
7
7
  from functools import wraps, cached_property
8
8
  import ctypes
9
+ import operator
9
10
 
10
11
  import numpy as np
11
12
  from numpy.polynomial import Polynomial
@@ -19,7 +20,8 @@ from scipy import integrate
19
20
  import scipy.special as sc
20
21
 
21
22
  import scipy.special._ufuncs as scu
22
- from scipy._lib._util import _lazyselect, _lazywhere
23
+ from scipy._lib._util import _lazyselect
24
+ import scipy._lib.array_api_extra as xpx
23
25
 
24
26
  from . import _stats
25
27
  from ._tukeylambda_stats import (tukeylambda_variance as _tlvar,
@@ -27,7 +29,6 @@ from ._tukeylambda_stats import (tukeylambda_variance as _tlvar,
27
29
  from ._distn_infrastructure import (_vectorize_rvs_over_shapes,
28
30
  get_distribution_names, _kurtosis, _isintegral,
29
31
  rv_continuous, _skew, _get_fixed_fit_value, _check_shape, _ShapeInfo)
30
- from scipy.stats._distribution_infrastructure import _log1mexp
31
32
  from ._ksstats import kolmogn, kolmognp, kolmogni
32
33
  from ._constants import (_XMIN, _LOGXMIN, _EULER, _ZETA3, _SQRT_PI,
33
34
  _SQRT_2_OVER_PI, _LOG_PI, _LOG_SQRT_2_OVER_PI)
@@ -1031,17 +1032,16 @@ class betaprime_gen(rv_continuous):
1031
1032
  # use the following relationship of the incomplete beta function:
1032
1033
  # betainc(x, a, b) = 1 - betainc(1-x, b, a)
1033
1034
  # see gh-17631
1034
- return _lazywhere(
1035
- x > 1, [x, a, b],
1036
- lambda x_, a_, b_: beta._sf(1/(1+x_), b_, a_),
1037
- f2=lambda x_, a_, b_: beta._cdf(x_/(1+x_), a_, b_))
1035
+ return xpx.apply_where(
1036
+ x > 1, (x, a, b),
1037
+ lambda x_, a_, b_: beta._sf(1 / (1 + x_), b_, a_),
1038
+ lambda x_, a_, b_: beta._cdf(x_ / (1 + x_), a_, b_))
1038
1039
 
1039
1040
  def _sf(self, x, a, b):
1040
- return _lazywhere(
1041
- x > 1, [x, a, b],
1042
- lambda x_, a_, b_: beta._cdf(1/(1+x_), b_, a_),
1043
- f2=lambda x_, a_, b_: beta._sf(x_/(1+x_), a_, b_)
1044
- )
1041
+ return xpx.apply_where(
1042
+ x > 1, (x, a, b),
1043
+ lambda x_, a_, b_: beta._cdf(1 / (1 + x_), b_, a_),
1044
+ lambda x_, a_, b_: beta._sf(x_ / (1 + x_), a_, b_))
1045
1045
 
1046
1046
  def _ppf(self, p, a, b):
1047
1047
  p, a, b = np.broadcast_arrays(p, a, b)
@@ -1062,10 +1062,10 @@ class betaprime_gen(rv_continuous):
1062
1062
  return out
1063
1063
 
1064
1064
  def _munp(self, n, a, b):
1065
- return _lazywhere(
1065
+ return xpx.apply_where(
1066
1066
  b > n, (a, b),
1067
1067
  lambda a, b: np.prod([(a+i-1)/(b-i) for i in range(1, int(n)+1)], axis=0),
1068
- fillvalue=np.inf)
1068
+ fill_value=np.inf)
1069
1069
 
1070
1070
 
1071
1071
  betaprime = betaprime_gen(a=0.0, name='betaprime')
@@ -1185,26 +1185,22 @@ class burr_gen(rv_continuous):
1185
1185
 
1186
1186
  def _pdf(self, x, c, d):
1187
1187
  # burr.pdf(x, c, d) = c * d * x**(-c-1) * (1+x**(-c))**(-d-1)
1188
- output = _lazywhere(
1189
- x == 0, [x, c, d],
1188
+ output = xpx.apply_where(
1189
+ x == 0, (x, c, d),
1190
1190
  lambda x_, c_, d_: c_ * d_ * (x_**(c_*d_-1)) / (1 + x_**c_),
1191
- f2=lambda x_, c_, d_: (c_ * d_ * (x_ ** (-c_ - 1.0)) /
1192
- ((1 + x_ ** (-c_)) ** (d_ + 1.0))))
1193
- if output.ndim == 0:
1194
- return output[()]
1195
- return output
1191
+ lambda x_, c_, d_: (c_ * d_ * (x_ ** (-c_ - 1.0)) /
1192
+ ((1 + x_ ** (-c_)) ** (d_ + 1.0))))
1193
+ return output[()] if output.ndim == 0 else output
1196
1194
 
1197
1195
  def _logpdf(self, x, c, d):
1198
- output = _lazywhere(
1199
- x == 0, [x, c, d],
1196
+ output = xpx.apply_where(
1197
+ x == 0, (x, c, d),
1200
1198
  lambda x_, c_, d_: (np.log(c_) + np.log(d_) + sc.xlogy(c_*d_ - 1, x_)
1201
1199
  - (d_+1) * sc.log1p(x_**(c_))),
1202
- f2=lambda x_, c_, d_: (np.log(c_) + np.log(d_)
1203
- + sc.xlogy(-c_ - 1, x_)
1204
- - sc.xlog1py(d_+1, x_**(-c_))))
1205
- if output.ndim == 0:
1206
- return output[()]
1207
- return output
1200
+ lambda x_, c_, d_: (np.log(c_) + np.log(d_)
1201
+ + sc.xlogy(-c_ - 1, x_)
1202
+ - sc.xlog1py(d_+1, x_**(-c_))))
1203
+ return output[()] if output.ndim == 0 else output
1208
1204
 
1209
1205
  def _cdf(self, x, c, d):
1210
1206
  return (1 + x**(-c))**(-d)
@@ -1232,18 +1228,16 @@ class burr_gen(rv_continuous):
1232
1228
  mu = np.where(c > 1.0, e1, np.nan)
1233
1229
  mu2_if_c = e2 - mu**2
1234
1230
  mu2 = np.where(c > 2.0, mu2_if_c, np.nan)
1235
- g1 = _lazywhere(
1236
- c > 3.0,
1237
- (c, e1, e2, e3, mu2_if_c),
1238
- lambda c, e1, e2, e3, mu2_if_c: ((e3 - 3*e2*e1 + 2*e1**3)
1239
- / np.sqrt((mu2_if_c)**3)),
1240
- fillvalue=np.nan)
1241
- g2 = _lazywhere(
1242
- c > 4.0,
1243
- (c, e1, e2, e3, e4, mu2_if_c),
1244
- lambda c, e1, e2, e3, e4, mu2_if_c: (
1231
+ g1 = xpx.apply_where(
1232
+ c > 3.0, (e1, e2, e3, mu2_if_c),
1233
+ lambda e1, e2, e3, mu2_if_c: ((e3 - 3*e2*e1 + 2*e1**3)
1234
+ / np.sqrt((mu2_if_c)**3)),
1235
+ fill_value=np.nan)
1236
+ g2 = xpx.apply_where(
1237
+ c > 4.0, (e1, e2, e3, e4, mu2_if_c),
1238
+ lambda e1, e2, e3, e4, mu2_if_c: (
1245
1239
  ((e4 - 4*e3*e1 + 6*e2*e1**2 - 3*e1**4) / mu2_if_c**2) - 3),
1246
- fillvalue=np.nan)
1240
+ fill_value=np.nan)
1247
1241
  if np.ndim(c) == 0:
1248
1242
  return mu.item(), mu2.item(), g1.item(), g2.item()
1249
1243
  return mu, mu2, g1, g2
@@ -1253,9 +1247,8 @@ class burr_gen(rv_continuous):
1253
1247
  nc = 1. * n / c
1254
1248
  return d * sc.beta(1.0 - nc, d + nc)
1255
1249
  n, c, d = np.asarray(n), np.asarray(c), np.asarray(d)
1256
- return _lazywhere((c > n) & (n == n) & (d == d), (c, d, n),
1257
- lambda c, d, n: __munp(n, c, d),
1258
- np.nan)
1250
+ return xpx.apply_where((c > n) & (n == n) & (d == d),
1251
+ (n, c, d), __munp, fill_value=np.nan)
1259
1252
 
1260
1253
 
1261
1254
  burr = burr_gen(a=0.0, name='burr')
@@ -1344,8 +1337,8 @@ class burr12_gen(rv_continuous):
1344
1337
  nc = 1. * n / c
1345
1338
  return d * sc.beta(1.0 + nc, d - nc)
1346
1339
 
1347
- return _lazywhere(c * d > n, (n, c, d), moment_if_exists,
1348
- fillvalue=np.nan)
1340
+ return xpx.apply_where(c * d > n, (n, c, d), moment_if_exists,
1341
+ fill_value=np.nan)
1349
1342
 
1350
1343
 
1351
1344
  burr12 = burr12_gen(a=0.0, name='burr12')
@@ -1478,14 +1471,13 @@ class cauchy_gen(rv_continuous):
1478
1471
  # = -log(pi) - (2log(|x|) + log1p(1/x**2))
1479
1472
  # are used here.
1480
1473
  absx = np.abs(x)
1481
- # In the following _lazywhere, `f` provides better precision than `f2`
1474
+ # In the following apply_where, `f1` provides better precision than `f2`
1482
1475
  # for small and moderate x, while `f2` avoids the overflow that can
1483
1476
  # occur with absx**2.
1484
- y = _lazywhere(absx < 1, (absx,),
1485
- f=lambda absx: -_LOG_PI - np.log1p(absx**2),
1486
- f2=lambda absx: (-_LOG_PI -
1487
- (2*np.log(absx) + np.log1p((1/absx)**2))))
1488
- return y
1477
+ return xpx.apply_where(
1478
+ absx < 1, absx,
1479
+ lambda absx: -_LOG_PI - np.log1p(absx**2),
1480
+ lambda absx: (-_LOG_PI - (2*np.log(absx) + np.log1p((1/absx)**2))))
1489
1481
 
1490
1482
  def _cdf(self, x):
1491
1483
  return np.arctan2(1, -x)/np.pi
@@ -1594,8 +1586,7 @@ class chi_gen(rv_continuous):
1594
1586
  return (0.5 + np.log(np.pi)/2 - (df**-1)/6 - (df**-2)/6
1595
1587
  - 4/45*(df**-3) + (df**-4)/15)
1596
1588
 
1597
- return _lazywhere(df < 3e2, (df, ), regular_formula,
1598
- f2=asymptotic_formula)
1589
+ return xpx.apply_where(df < 300, df, regular_formula, asymptotic_formula)
1599
1590
 
1600
1591
 
1601
1592
  chi = chi_gen(a=0.0, name='chi')
@@ -1685,9 +1676,8 @@ class chi2_gen(rv_continuous):
1685
1676
  return (h*(-2/3 + h*(-1/3 + h*(-4/45 + h/7.5))) +
1686
1677
  0.5*np.log(half_df) + c)
1687
1678
 
1688
- return _lazywhere(half_df < 125, (half_df, ),
1689
- regular_formula,
1690
- f2=asymptotic_formula)
1679
+ return xpx.apply_where(half_df < 125, half_df,
1680
+ regular_formula, asymptotic_formula)
1691
1681
 
1692
1682
 
1693
1683
  chi2 = chi2_gen(a=0.0, name='chi2')
@@ -1723,9 +1713,9 @@ class cosine_gen(rv_continuous):
1723
1713
 
1724
1714
  def _logpdf(self, x):
1725
1715
  c = np.cos(x)
1726
- return _lazywhere(c != -1, (c,),
1727
- lambda c: np.log1p(c) - np.log(2*np.pi),
1728
- fillvalue=-np.inf)
1716
+ return xpx.apply_where(c != -1, c,
1717
+ lambda c: np.log1p(c) - np.log(2*np.pi),
1718
+ fill_value=-np.inf)
1729
1719
 
1730
1720
  def _cdf(self, x):
1731
1721
  return scu._cosine_cdf(x)
@@ -1945,7 +1935,7 @@ class dpareto_lognorm_gen(rv_continuous):
1945
1935
  return out[()]
1946
1936
 
1947
1937
  def _logsf(self, x, u, s, a, b):
1948
- return _log1mexp(self._logcdf(x, u, s, a, b))
1938
+ return scu._log1mexp(self._logcdf(x, u, s, a, b))
1949
1939
 
1950
1940
  # Infrastructure doesn't seem to do this, so...
1951
1941
 
@@ -2589,28 +2579,28 @@ class f_gen(rv_continuous):
2589
2579
  v1, v2 = 1. * dfn, 1. * dfd
2590
2580
  v2_2, v2_4, v2_6, v2_8 = v2 - 2., v2 - 4., v2 - 6., v2 - 8.
2591
2581
 
2592
- mu = _lazywhere(
2582
+ mu = xpx.apply_where(
2593
2583
  v2 > 2, (v2, v2_2),
2594
2584
  lambda v2, v2_2: v2 / v2_2,
2595
- np.inf)
2585
+ fill_value=np.inf)
2596
2586
 
2597
- mu2 = _lazywhere(
2587
+ mu2 = xpx.apply_where(
2598
2588
  v2 > 4, (v1, v2, v2_2, v2_4),
2599
2589
  lambda v1, v2, v2_2, v2_4:
2600
2590
  2 * v2 * v2 * (v1 + v2_2) / (v1 * v2_2**2 * v2_4),
2601
- np.inf)
2591
+ fill_value=np.inf)
2602
2592
 
2603
- g1 = _lazywhere(
2593
+ g1 = xpx.apply_where(
2604
2594
  v2 > 6, (v1, v2_2, v2_4, v2_6),
2605
2595
  lambda v1, v2_2, v2_4, v2_6:
2606
2596
  (2 * v1 + v2_2) / v2_6 * np.sqrt(v2_4 / (v1 * (v1 + v2_2))),
2607
- np.nan)
2597
+ fill_value=np.nan)
2608
2598
  g1 *= np.sqrt(8.)
2609
2599
 
2610
- g2 = _lazywhere(
2600
+ g2 = xpx.apply_where(
2611
2601
  v2 > 8, (g1, v2_6, v2_8),
2612
2602
  lambda g1, v2_6, v2_8: (8 + g1 * g1 * v2_6) / v2_8,
2613
- np.nan)
2603
+ fill_value=np.nan)
2614
2604
  g2 *= 3. / 2.
2615
2605
 
2616
2606
  return mu, mu2, g1, g2
@@ -3127,14 +3117,15 @@ class genlogistic_gen(rv_continuous):
3127
3117
  return mu, mu2, g1, g2
3128
3118
 
3129
3119
  def _entropy(self, c):
3130
- return _lazywhere(c < 8e6, (c, ),
3131
- lambda c: -np.log(c) + sc.psi(c + 1) + _EULER + 1,
3132
- # asymptotic expansion: psi(c) ~ log(c) - 1/(2 * c)
3133
- # a = -log(c) + psi(c + 1)
3134
- # = -log(c) + psi(c) + 1/c
3135
- # ~ -log(c) + log(c) - 1/(2 * c) + 1/c
3136
- # = 1/(2 * c)
3137
- f2=lambda c: 1/(2 * c) + _EULER + 1)
3120
+ return xpx.apply_where(
3121
+ c < 8e6, c,
3122
+ lambda c: -np.log(c) + sc.psi(c + 1) + _EULER + 1,
3123
+ # asymptotic expansion: psi(c) ~ log(c) - 1 / (2 * c)
3124
+ # a = -log(c) + psi(c + 1)
3125
+ # = -log(c) + psi(c) + 1 / c
3126
+ # ~ -log(c) + log(c) - 1 / (2 * c) + 1 / c
3127
+ # = 1 / (2 * c)
3128
+ lambda c: 1 / (2 * c) + _EULER + 1)
3138
3129
 
3139
3130
 
3140
3131
  genlogistic = genlogistic_gen(name='genlogistic')
@@ -3184,10 +3175,9 @@ class genpareto_gen(rv_continuous):
3184
3175
 
3185
3176
  def _get_support(self, c):
3186
3177
  c = np.asarray(c)
3187
- b = _lazywhere(c < 0, (c,),
3188
- lambda c: -1. / c,
3189
- np.inf)
3190
- a = np.where(c >= 0, self.a, self.a)
3178
+ a = np.broadcast_arrays(self.a, c)[0].copy()
3179
+ b = xpx.apply_where(c < 0, c, lambda c: -1. / c,
3180
+ fill_value=np.inf)
3191
3181
  return a, b
3192
3182
 
3193
3183
  def _pdf(self, x, c):
@@ -3195,9 +3185,9 @@ class genpareto_gen(rv_continuous):
3195
3185
  return np.exp(self._logpdf(x, c))
3196
3186
 
3197
3187
  def _logpdf(self, x, c):
3198
- return _lazywhere((x == x) & (c != 0), (x, c),
3199
- lambda x, c: -sc.xlog1py(c + 1., c*x) / c,
3200
- -x)
3188
+ return xpx.apply_where((x == x) & (c != 0), (x, c),
3189
+ lambda x, c: -sc.xlog1py(c + 1., c*x) / c,
3190
+ fill_value=-x)
3201
3191
 
3202
3192
  def _cdf(self, x, c):
3203
3193
  return -sc.inv_boxcox1p(-x, -c)
@@ -3206,9 +3196,9 @@ class genpareto_gen(rv_continuous):
3206
3196
  return sc.inv_boxcox(-x, -c)
3207
3197
 
3208
3198
  def _logsf(self, x, c):
3209
- return _lazywhere((x == x) & (c != 0), (x, c),
3210
- lambda x, c: -sc.log1p(c*x) / c,
3211
- -x)
3199
+ return xpx.apply_where((x == x) & (c != 0), (x, c),
3200
+ lambda x, c: -sc.log1p(c*x) / c,
3201
+ fill_value=-x)
3212
3202
 
3213
3203
  def _ppf(self, q, c):
3214
3204
  return -sc.boxcox1p(-q, -c)
@@ -3217,44 +3207,42 @@ class genpareto_gen(rv_continuous):
3217
3207
  return -sc.boxcox(q, -c)
3218
3208
 
3219
3209
  def _stats(self, c, moments='mv'):
3220
- if 'm' not in moments:
3221
- m = None
3222
- else:
3223
- m = _lazywhere(c < 1, (c,),
3224
- lambda xi: 1/(1 - xi),
3225
- np.inf)
3226
- if 'v' not in moments:
3227
- v = None
3228
- else:
3229
- v = _lazywhere(c < 1/2, (c,),
3230
- lambda xi: 1 / (1 - xi)**2 / (1 - 2*xi),
3231
- np.nan)
3232
- if 's' not in moments:
3233
- s = None
3234
- else:
3235
- s = _lazywhere(c < 1/3, (c,),
3236
- lambda xi: (2 * (1 + xi) * np.sqrt(1 - 2*xi) /
3237
- (1 - 3*xi)),
3238
- np.nan)
3239
- if 'k' not in moments:
3240
- k = None
3241
- else:
3242
- k = _lazywhere(c < 1/4, (c,),
3243
- lambda xi: (3 * (1 - 2*xi) * (2*xi**2 + xi + 3) /
3244
- (1 - 3*xi) / (1 - 4*xi) - 3),
3245
- np.nan)
3210
+ m, v, s, k = None, None, None, None
3211
+
3212
+ if 'm' in moments:
3213
+ m = xpx.apply_where(c < 1, c,
3214
+ lambda xi: 1 / (1 - xi),
3215
+ fill_value=np.inf)
3216
+
3217
+ if 'v' in moments:
3218
+ v = xpx.apply_where(c < 1/2, c,
3219
+ lambda xi: 1 / (1 - xi)**2 / (1 - 2 * xi),
3220
+ fill_value=np.nan)
3221
+
3222
+ if 's' in moments:
3223
+ s = xpx.apply_where(
3224
+ c < 1/3, c,
3225
+ lambda xi: 2 * (1 + xi) * np.sqrt(1 - 2*xi) / (1 - 3*xi),
3226
+ fill_value=np.nan)
3227
+
3228
+ if 'k' in moments:
3229
+ k = xpx.apply_where(
3230
+ c < 1/4, c,
3231
+ lambda xi: 3 * (1 - 2*xi) * (2*xi**2 + xi + 3)
3232
+ / (1 - 3*xi) / (1 - 4*xi) - 3,
3233
+ fill_value=np.nan)
3234
+
3246
3235
  return m, v, s, k
3247
3236
 
3248
3237
  def _munp(self, n, c):
3249
- def __munp(n, c):
3238
+ def __munp(c):
3250
3239
  val = 0.0
3251
3240
  k = np.arange(0, n + 1)
3252
3241
  for ki, cnk in zip(k, sc.comb(n, k)):
3253
3242
  val = val + cnk * (-1) ** ki / (1.0 - c * ki)
3254
3243
  return np.where(c * n < 1, val * (-1.0 / c) ** n, np.inf)
3255
- return _lazywhere(c != 0, (c,),
3256
- lambda c: __munp(n, c),
3257
- sc.gamma(n + 1))
3244
+
3245
+ return xpx.apply_where(c != 0, c, __munp, fill_value=sc.gamma(n + 1))
3258
3246
 
3259
3247
  def _entropy(self, c):
3260
3248
  return 1. + c
@@ -3382,8 +3370,10 @@ class genextreme_gen(rv_continuous):
3382
3370
 
3383
3371
  def _loglogcdf(self, x, c):
3384
3372
  # Returns log(-log(cdf(x, c)))
3385
- return _lazywhere((x == x) & (c != 0), (x, c),
3386
- lambda x, c: sc.log1p(-c*x)/c, -x)
3373
+ return xpx.apply_where(
3374
+ (x == x) & (c != 0), (x, c),
3375
+ lambda x, c: sc.log1p(-c*x)/c,
3376
+ fill_value=-x)
3387
3377
 
3388
3378
  def _pdf(self, x, c):
3389
3379
  # genextreme.pdf(x, c) =
@@ -3392,16 +3382,19 @@ class genextreme_gen(rv_continuous):
3392
3382
  return np.exp(self._logpdf(x, c))
3393
3383
 
3394
3384
  def _logpdf(self, x, c):
3395
- cx = _lazywhere((x == x) & (c != 0), (x, c), lambda x, c: c*x, 0.0)
3385
+ # Suppress warnings 0 * inf
3386
+ cx = xpx.apply_where((x == x) & (c != 0), (c, x),
3387
+ operator.mul, fill_value=0.0)
3396
3388
  logex2 = sc.log1p(-cx)
3397
3389
  logpex2 = self._loglogcdf(x, c)
3398
3390
  pex2 = np.exp(logpex2)
3399
3391
  # Handle special cases
3400
3392
  np.putmask(logpex2, (c == 0) & (x == -np.inf), 0.0)
3401
- logpdf = _lazywhere(~((cx == 1) | (cx == -np.inf)),
3402
- (pex2, logpex2, logex2),
3403
- lambda pex2, lpex2, lex2: -pex2 + lpex2 - lex2,
3404
- fillvalue=-np.inf)
3393
+ logpdf = xpx.apply_where(
3394
+ ~((cx == 1) | (cx == -np.inf)),
3395
+ (pex2, logpex2, logex2),
3396
+ lambda pex2, lpex2, lex2: -pex2 + lpex2 - lex2,
3397
+ fill_value=-np.inf)
3405
3398
  np.putmask(logpdf, (c == 1) & (x == 1), 0.0)
3406
3399
  return logpdf
3407
3400
 
@@ -3416,13 +3409,17 @@ class genextreme_gen(rv_continuous):
3416
3409
 
3417
3410
  def _ppf(self, q, c):
3418
3411
  x = -np.log(-np.log(q))
3419
- return _lazywhere((x == x) & (c != 0), (x, c),
3420
- lambda x, c: -sc.expm1(-c * x) / c, x)
3412
+ return xpx.apply_where(
3413
+ (x == x) & (c != 0), (x, c),
3414
+ lambda x, c: -sc.expm1(-c * x) / c,
3415
+ fill_value=x)
3421
3416
 
3422
3417
  def _isf(self, q, c):
3423
3418
  x = -np.log(-sc.log1p(-q))
3424
- return _lazywhere((x == x) & (c != 0), (x, c),
3425
- lambda x, c: -sc.expm1(-c * x) / c, x)
3419
+ return xpx.apply_where(
3420
+ (x == x) & (c != 0), (x, c),
3421
+ lambda x, c: -sc.expm1(-c * x) / c,
3422
+ fill_value=x)
3426
3423
 
3427
3424
  def _stats(self, c):
3428
3425
  def g(n):
@@ -3432,29 +3429,42 @@ class genextreme_gen(rv_continuous):
3432
3429
  g3 = g(3)
3433
3430
  g4 = g(4)
3434
3431
  g2mg12 = np.where(abs(c) < 1e-7, (c*np.pi)**2.0/6.0, g2-g1**2.0)
3435
- gam2k = np.where(abs(c) < 1e-7, np.pi**2.0/6.0,
3436
- sc.expm1(sc.gammaln(2.0*c+1.0)-2*sc.gammaln(c + 1.0))/c**2.0)
3432
+ def gam2k_f(c):
3433
+ return sc.expm1(sc.gammaln(2.0*c+1.0)-2*sc.gammaln(c + 1.0))/c**2.0
3434
+ gam2k = xpx.apply_where(abs(c) >= 1e-7, c, gam2k_f, fill_value=np.pi**2.0/6.0)
3437
3435
  eps = 1e-14
3438
- gamk = np.where(abs(c) < eps, -_EULER, sc.expm1(sc.gammaln(c + 1))/c)
3436
+ def gamk_f(c):
3437
+ return sc.expm1(sc.gammaln(c + 1))/c
3438
+ gamk = xpx.apply_where(abs(c) >= eps, c, gamk_f, fill_value=-_EULER)
3439
3439
 
3440
+ # mean
3440
3441
  m = np.where(c < -1.0, np.nan, -gamk)
3442
+
3443
+ # variance
3441
3444
  v = np.where(c < -0.5, np.nan, g1**2.0*gam2k)
3442
3445
 
3443
3446
  # skewness
3444
- sk1 = _lazywhere(c >= -1./3,
3445
- (c, g1, g2, g3, g2mg12),
3446
- lambda c, g1, g2, g3, g2mg12:
3447
- np.sign(c)*(-g3 + (g2 + 2*g2mg12)*g1)/g2mg12**1.5,
3448
- fillvalue=np.nan)
3449
- sk = np.where(abs(c) <= eps**0.29, 12*np.sqrt(6)*_ZETA3/np.pi**3, sk1)
3447
+ def sk1_eval(c, *args):
3448
+ def sk1_eval_f(c, g1, g2, g3, g2mg12):
3449
+ return np.sign(c)*(-g3 + (g2 + 2*g2mg12)*g1)/g2mg12**1.5
3450
+ return xpx.apply_where(c >= -1./3, (c, *args),
3451
+ sk1_eval_f, fill_value=np.nan)
3452
+
3453
+ sk_fill = 12*np.sqrt(6)*_ZETA3/np.pi**3
3454
+ args = (g1, g2, g3, g2mg12)
3455
+ sk = xpx.apply_where(abs(c) > eps**0.29, (c, *args),
3456
+ sk1_eval, fill_value=sk_fill)
3450
3457
 
3451
3458
  # kurtosis
3452
- ku1 = _lazywhere(c >= -1./4,
3453
- (g1, g2, g3, g4, g2mg12),
3454
- lambda g1, g2, g3, g4, g2mg12:
3455
- (g4 + (-4*g3 + 3*(g2 + g2mg12)*g1)*g1)/g2mg12**2,
3456
- fillvalue=np.nan)
3457
- ku = np.where(abs(c) <= (eps)**0.23, 12.0/5.0, ku1-3.0)
3459
+ def ku1_eval(c, *args):
3460
+ def ku1_eval_f(g1, g2, g3, g4, g2mg12):
3461
+ return (g4 + (-4*g3 + 3*(g2 + g2mg12)*g1)*g1)/g2mg12**2 - 3
3462
+ return xpx.apply_where(c >= -1./4, args, ku1_eval_f, fill_value=np.nan)
3463
+
3464
+ args = (g1, g2, g3, g4, g2mg12)
3465
+ ku = xpx.apply_where(abs(c) > eps**0.23, (c, *args),
3466
+ ku1_eval, fill_value=12.0/5.0)
3467
+
3458
3468
  return m, v, sk, ku
3459
3469
 
3460
3470
  def _fitstart(self, data):
@@ -3617,8 +3627,7 @@ class gamma_gen(rv_continuous):
3617
3627
  return (0.5 * (1. + np.log(2*np.pi) + np.log(a)) - 1/(3 * a)
3618
3628
  - (a**-2.)/12 - (a**-3.)/90 + (a**-4.)/120)
3619
3629
 
3620
- return _lazywhere(a < 250, (a, ), regular_formula,
3621
- f2=asymptotic_formula)
3630
+ return xpx.apply_where(a < 250, a, regular_formula, asymptotic_formula)
3622
3631
 
3623
3632
  def _fitstart(self, data):
3624
3633
  # The skewness of the gamma distribution is `2 / np.sqrt(a)`.
@@ -3848,10 +3857,10 @@ class gengamma_gen(rv_continuous):
3848
3857
  return np.exp(self._logpdf(x, a, c))
3849
3858
 
3850
3859
  def _logpdf(self, x, a, c):
3851
- return _lazywhere((x != 0) | (c > 0), (x, c),
3852
- lambda x, c: (np.log(abs(c)) + sc.xlogy(c*a - 1, x)
3853
- - x**c - sc.gammaln(a)),
3854
- fillvalue=-np.inf)
3860
+ return xpx.apply_where(
3861
+ (x != 0) | (c > 0), (x, c),
3862
+ lambda x, c: (np.log(abs(c)) + sc.xlogy(c*a - 1, x) - x**c - sc.gammaln(a)),
3863
+ fill_value=-np.inf)
3855
3864
 
3856
3865
  def _cdf(self, x, a, c):
3857
3866
  xc = x**c
@@ -3897,8 +3906,7 @@ class gengamma_gen(rv_continuous):
3897
3906
  - np.log(np.abs(c)) + (a**-1.)/6 - (a**-3.)/90
3898
3907
  + (np.log(a) - (a**-1.)/2 - (a**-2.)/12 + (a**-4.)/120)/c)
3899
3908
 
3900
- h = _lazywhere(a >= 2e2, (a, c), f=asymptotic, f2=regular)
3901
- return h
3909
+ return xpx.apply_where(a >= 200, (a, c), asymptotic, regular)
3902
3910
 
3903
3911
 
3904
3912
  gengamma = gengamma_gen(a=0.0, name='gengamma')
@@ -4601,9 +4609,9 @@ class halflogistic_gen(rv_continuous):
4601
4609
  return 2 * sc.expit(-x)
4602
4610
 
4603
4611
  def _isf(self, q):
4604
- return _lazywhere(q < 0.5, (q, ),
4605
- lambda q: -sc.logit(0.5 * q),
4606
- f2=lambda q: 2*np.arctanh(1 - q))
4612
+ return xpx.apply_where(q < 0.5, q,
4613
+ lambda q: -sc.logit(0.5 * q),
4614
+ lambda q: 2*np.arctanh(1 - q))
4607
4615
 
4608
4616
  def _munp(self, n):
4609
4617
  if n == 0:
@@ -4932,19 +4940,23 @@ class invgamma_gen(rv_continuous):
4932
4940
  return 1.0 / sc.gammaincinv(a, q)
4933
4941
 
4934
4942
  def _stats(self, a, moments='mvsk'):
4935
- m1 = _lazywhere(a > 1, (a,), lambda x: 1. / (x - 1.), np.inf)
4936
- m2 = _lazywhere(a > 2, (a,), lambda x: 1. / (x - 1.)**2 / (x - 2.),
4937
- np.inf)
4943
+ m1 = xpx.apply_where(a > 1, a,
4944
+ lambda x: 1. / (x - 1.),
4945
+ fill_value=np.inf)
4946
+ m2 = xpx.apply_where(a > 2, a,
4947
+ lambda x: 1. / (x - 1.)**2 / (x - 2.),
4948
+ fill_value=np.inf)
4938
4949
 
4939
4950
  g1, g2 = None, None
4940
4951
  if 's' in moments:
4941
- g1 = _lazywhere(
4942
- a > 3, (a,),
4943
- lambda x: 4. * np.sqrt(x - 2.) / (x - 3.), np.nan)
4952
+ g1 = xpx.apply_where(a > 3, a,
4953
+ lambda x: 4. * np.sqrt(x - 2.) / (x - 3.),
4954
+ fill_value=np.nan)
4944
4955
  if 'k' in moments:
4945
- g2 = _lazywhere(
4946
- a > 4, (a,),
4947
- lambda x: 6. * (5. * x - 11.) / (x - 3.) / (x - 4.), np.nan)
4956
+ g2 = xpx.apply_where(a > 4, a,
4957
+ lambda x: 6. * (5. * x - 11.) / (x - 3.) / (x - 4.),
4958
+ fill_value=np.nan)
4959
+
4948
4960
  return m1, m2, g1, g2
4949
4961
 
4950
4962
  def _entropy(self, a):
@@ -4959,7 +4971,7 @@ class invgamma_gen(rv_continuous):
4959
4971
  + 2/3*a**-1. + a**-2./12 - a**-3./90 - a**-4./120)
4960
4972
  return h
4961
4973
 
4962
- h = _lazywhere(a >= 2e2, (a,), f=asymptotic, f2=regular)
4974
+ h = xpx.apply_where(a >= 200, a, asymptotic, regular)
4963
4975
  return h
4964
4976
 
4965
4977
 
@@ -5019,10 +5031,10 @@ class invgauss_gen(rv_continuous):
5019
5031
  def _pdf(self, x, mu):
5020
5032
  # invgauss.pdf(x, mu) =
5021
5033
  # 1 / sqrt(2*pi*x**3) * exp(-(x-mu)**2/(2*x*mu**2))
5022
- return 1.0/np.sqrt(2*np.pi*x**3.0)*np.exp(-1.0/(2*x)*((x-mu)/mu)**2)
5034
+ return 1.0/np.sqrt(2*np.pi*x**3.0)*np.exp(-1.0/(2*x)*(x/mu - 1)**2)
5023
5035
 
5024
5036
  def _logpdf(self, x, mu):
5025
- return -0.5*np.log(2*np.pi) - 1.5*np.log(x) - ((x-mu)/mu)**2/(2*x)
5037
+ return -0.5*np.log(2*np.pi) - 1.5*np.log(x) - (x/mu - 1)**2/(2*x)
5026
5038
 
5027
5039
  # approach adapted from equations in
5028
5040
  # https://journal.r-project.org/archive/2016-1/giner-smyth.pdf,
@@ -5030,14 +5042,14 @@ class invgauss_gen(rv_continuous):
5030
5042
 
5031
5043
  def _logcdf(self, x, mu):
5032
5044
  fac = 1 / np.sqrt(x)
5033
- a = _norm_logcdf(fac * ((x / mu) - 1))
5034
- b = 2 / mu + _norm_logcdf(-fac * ((x / mu) + 1))
5045
+ a = _norm_logcdf(fac * (x/mu - 1))
5046
+ b = 2 / mu + _norm_logcdf(-fac * (x/mu + 1))
5035
5047
  return a + np.log1p(np.exp(b - a))
5036
5048
 
5037
5049
  def _logsf(self, x, mu):
5038
5050
  fac = 1 / np.sqrt(x)
5039
- a = _norm_logsf(fac * ((x / mu) - 1))
5040
- b = 2 / mu + _norm_logcdf(-fac * (x + mu) / mu)
5051
+ a = _norm_logsf(fac * (x/mu - 1))
5052
+ b = 2 / mu + _norm_logcdf(-fac * (x/mu + 1))
5041
5053
  return a + np.log1p(-np.exp(b - a))
5042
5054
 
5043
5055
  def _sf(self, x, mu):
@@ -5201,9 +5213,9 @@ class geninvgauss_gen(rv_continuous):
5201
5213
 
5202
5214
  def _logquasipdf(self, x, p, b):
5203
5215
  # log of the quasi-density (w/o normalizing constant) used in _rvs
5204
- return _lazywhere(x > 0, (x, p, b),
5205
- lambda x, p, b: (p - 1)*np.log(x) - b*(x + 1/x)/2,
5206
- -np.inf)
5216
+ return xpx.apply_where(x > 0, (x, p, b),
5217
+ lambda x, p, b: (p - 1)*np.log(x) - b*(x + 1/x)/2,
5218
+ fill_value=-np.inf)
5207
5219
 
5208
5220
  def _rvs(self, p, b, size=None, random_state=None):
5209
5221
  # if p and b are scalar, use _rvs_scalar, otherwise need to create
@@ -5751,11 +5763,11 @@ class jf_skew_t_gen(rv_continuous):
5751
5763
  return num / denom * sum_terms.sum()
5752
5764
 
5753
5765
  nth_moment_valid = (a > 0.5 * n) & (b > 0.5 * n) & (n >= 0)
5754
- return _lazywhere(
5766
+ return xpx.apply_where(
5755
5767
  nth_moment_valid,
5756
5768
  (n, a, b),
5757
5769
  np.vectorize(nth_moment, otypes=[np.float64]),
5758
- np.nan,
5770
+ fill_value=np.nan,
5759
5771
  )
5760
5772
 
5761
5773
 
@@ -6623,31 +6635,35 @@ class loggamma_gen(rv_continuous):
6623
6635
  # That is,
6624
6636
  # exp(x)**c/Gamma(c+1) = exp(log(exp(x)**c/Gamma(c+1)))
6625
6637
  # = exp(c*x - gammaln(c+1))
6626
- return _lazywhere(x < _LOGXMIN, (x, c),
6627
- lambda x, c: np.exp(c*x - sc.gammaln(c+1)),
6628
- f2=lambda x, c: sc.gammainc(c, np.exp(x)))
6638
+ return xpx.apply_where(
6639
+ x < _LOGXMIN, (x, c),
6640
+ lambda x, c: np.exp(c*x - sc.gammaln(c+1)),
6641
+ lambda x, c: sc.gammainc(c, np.exp(x)))
6629
6642
 
6630
6643
  def _ppf(self, q, c):
6631
6644
  # The expression used when g < _XMIN inverts the one term expansion
6632
6645
  # given in the comments of _cdf().
6633
6646
  g = sc.gammaincinv(c, q)
6634
- return _lazywhere(g < _XMIN, (g, q, c),
6635
- lambda g, q, c: (np.log(q) + sc.gammaln(c+1))/c,
6636
- f2=lambda g, q, c: np.log(g))
6647
+ return xpx.apply_where(
6648
+ g < _XMIN, (g, q, c),
6649
+ lambda g, q, c: (np.log(q) + sc.gammaln(c+1))/c,
6650
+ lambda g, q, c: np.log(g))
6637
6651
 
6638
6652
  def _sf(self, x, c):
6639
6653
  # See the comments for _cdf() for how x < _LOGXMIN is handled.
6640
- return _lazywhere(x < _LOGXMIN, (x, c),
6641
- lambda x, c: -np.expm1(c*x - sc.gammaln(c+1)),
6642
- f2=lambda x, c: sc.gammaincc(c, np.exp(x)))
6654
+ return xpx.apply_where(
6655
+ x < _LOGXMIN, (x, c),
6656
+ lambda x, c: -np.expm1(c*x - sc.gammaln(c+1)),
6657
+ lambda x, c: sc.gammaincc(c, np.exp(x)))
6643
6658
 
6644
6659
  def _isf(self, q, c):
6645
6660
  # The expression used when g < _XMIN inverts the complement of
6646
6661
  # the one term expansion given in the comments of _cdf().
6647
6662
  g = sc.gammainccinv(c, q)
6648
- return _lazywhere(g < _XMIN, (g, q, c),
6649
- lambda g, q, c: (np.log1p(-q) + sc.gammaln(c+1))/c,
6650
- f2=lambda g, q, c: np.log(g))
6663
+ return xpx.apply_where(
6664
+ g < _XMIN, (g, q, c),
6665
+ lambda g, q, c: (np.log1p(-q) + sc.gammaln(c+1))/c,
6666
+ lambda g, q, c: np.log(g))
6651
6667
 
6652
6668
  def _stats(self, c):
6653
6669
  # See, for example, "A Statistical Study of Log-Gamma Distribution", by
@@ -6669,8 +6685,7 @@ class loggamma_gen(rv_continuous):
6669
6685
  h = norm._entropy() + term
6670
6686
  return h
6671
6687
 
6672
- h = _lazywhere(c >= 45, (c, ), f=asymptotic, f2=regular)
6673
- return h
6688
+ return xpx.apply_where(c >= 45, c, asymptotic, regular)
6674
6689
 
6675
6690
 
6676
6691
  loggamma = loggamma_gen(name='loggamma')
@@ -6776,10 +6791,11 @@ loglaplace = loglaplace_gen(a=0.0, name='loglaplace')
6776
6791
 
6777
6792
 
6778
6793
  def _lognorm_logpdf(x, s):
6779
- return _lazywhere(x != 0, (x, s),
6780
- lambda x, s: (-np.log(x)**2 / (2 * s**2)
6781
- - np.log(s * x * np.sqrt(2 * np.pi))),
6782
- -np.inf)
6794
+ return xpx.apply_where(
6795
+ x != 0, (x, s),
6796
+ lambda x, s: (-np.log(x)**2 / (2 * s**2)
6797
+ - np.log(s * x * np.sqrt(2 * np.pi))),
6798
+ fill_value=-np.inf)
6783
6799
 
6784
6800
 
6785
6801
  class lognorm_gen(rv_continuous):
@@ -7174,7 +7190,7 @@ class mielke_gen(rv_continuous):
7174
7190
  # n-th moment is defined for -k < n < s
7175
7191
  return sc.gamma((k+n)/s)*sc.gamma(1-n/s)/sc.gamma(k/s)
7176
7192
 
7177
- return _lazywhere(n < s, (n, k, s), nth_moment, np.inf)
7193
+ return xpx.apply_where(n < s, (n, k, s), nth_moment, fill_value=np.inf)
7178
7194
 
7179
7195
 
7180
7196
  mielke = mielke_gen(a=0.0, name='mielke')
@@ -7742,11 +7758,11 @@ def _ncx2_log_pdf(x, df, nc):
7742
7758
  res = sc.xlogy(df2/2.0, x/nc) - 0.5*(xs - ns)**2
7743
7759
  corr = sc.ive(df2, xs*ns) / 2.0
7744
7760
  # Return res + np.log(corr) avoiding np.log(0)
7745
- return _lazywhere(
7761
+ return xpx.apply_where(
7746
7762
  corr > 0,
7747
7763
  (res, corr),
7748
- f=lambda r, c: r + np.log(c),
7749
- fillvalue=-np.inf)
7764
+ lambda r, c: r + np.log(c),
7765
+ fill_value=-np.inf)
7750
7766
 
7751
7767
 
7752
7768
  class ncx2_gen(rv_continuous):
@@ -7797,39 +7813,33 @@ class ncx2_gen(rv_continuous):
7797
7813
  return random_state.noncentral_chisquare(df, nc, size)
7798
7814
 
7799
7815
  def _logpdf(self, x, df, nc):
7800
- cond = np.ones_like(x, dtype=bool) & (nc != 0)
7801
- return _lazywhere(cond, (x, df, nc), f=_ncx2_log_pdf,
7802
- f2=lambda x, df, _: chi2._logpdf(x, df))
7816
+ return xpx.apply_where(nc != 0, (x, df, nc), _ncx2_log_pdf,
7817
+ lambda x, df, _: chi2._logpdf(x, df))
7803
7818
 
7804
7819
  def _pdf(self, x, df, nc):
7805
- cond = np.ones_like(x, dtype=bool) & (nc != 0)
7806
7820
  with np.errstate(over='ignore'): # see gh-17432
7807
- return _lazywhere(cond, (x, df, nc), f=scu._ncx2_pdf,
7808
- f2=lambda x, df, _: chi2._pdf(x, df))
7821
+ return xpx.apply_where(nc != 0, (x, df, nc), scu._ncx2_pdf,
7822
+ lambda x, df, _: chi2._pdf(x, df))
7809
7823
 
7810
7824
  def _cdf(self, x, df, nc):
7811
- cond = np.ones_like(x, dtype=bool) & (nc != 0)
7812
7825
  with np.errstate(over='ignore'): # see gh-17432
7813
- return _lazywhere(cond, (x, df, nc), f=scu._ncx2_cdf,
7814
- f2=lambda x, df, _: chi2._cdf(x, df))
7826
+ return xpx.apply_where(nc != 0, (x, df, nc), scu._ncx2_cdf,
7827
+ lambda x, df, _: chi2._cdf(x, df))
7815
7828
 
7816
7829
  def _ppf(self, q, df, nc):
7817
- cond = np.ones_like(q, dtype=bool) & (nc != 0)
7818
7830
  with np.errstate(over='ignore'): # see gh-17432
7819
- return _lazywhere(cond, (q, df, nc), f=scu._ncx2_ppf,
7820
- f2=lambda x, df, _: chi2._ppf(x, df))
7831
+ return xpx.apply_where(nc != 0, (q, df, nc), scu._ncx2_ppf,
7832
+ lambda x, df, _: chi2._ppf(x, df))
7821
7833
 
7822
7834
  def _sf(self, x, df, nc):
7823
- cond = np.ones_like(x, dtype=bool) & (nc != 0)
7824
7835
  with np.errstate(over='ignore'): # see gh-17432
7825
- return _lazywhere(cond, (x, df, nc), f=scu._ncx2_sf,
7826
- f2=lambda x, df, _: chi2._sf(x, df))
7836
+ return xpx.apply_where(nc != 0, (x, df, nc), scu._ncx2_sf,
7837
+ lambda x, df, _: chi2._sf(x, df))
7827
7838
 
7828
7839
  def _isf(self, x, df, nc):
7829
- cond = np.ones_like(x, dtype=bool) & (nc != 0)
7830
7840
  with np.errstate(over='ignore'): # see gh-17432
7831
- return _lazywhere(cond, (x, df, nc), f=scu._ncx2_isf,
7832
- f2=lambda x, df, _: chi2._isf(x, df))
7841
+ return xpx.apply_where(nc != 0, (x, df, nc), scu._ncx2_isf,
7842
+ lambda x, df, _: chi2._isf(x, df))
7833
7843
 
7834
7844
  def _stats(self, df, nc):
7835
7845
  _ncx2_mean = df + nc
@@ -7988,13 +7998,10 @@ class t_gen(rv_continuous):
7988
7998
  return random_state.standard_t(df, size=size)
7989
7999
 
7990
8000
  def _pdf(self, x, df):
7991
- return _lazywhere(
8001
+ return xpx.apply_where(
7992
8002
  df == np.inf, (x, df),
7993
- f=lambda x, df: norm._pdf(x),
7994
- f2=lambda x, df: (
7995
- np.exp(self._logpdf(x, df))
7996
- )
7997
- )
8003
+ lambda x, df: norm._pdf(x),
8004
+ lambda x, df: np.exp(self._logpdf(x, df)))
7998
8005
 
7999
8006
  def _logpdf(self, x, df):
8000
8007
 
@@ -8006,7 +8013,7 @@ class t_gen(rv_continuous):
8006
8013
  def norm_logpdf(x, df):
8007
8014
  return norm._logpdf(x)
8008
8015
 
8009
- return _lazywhere(df == np.inf, (x, df, ), f=norm_logpdf, f2=t_logpdf)
8016
+ return xpx.apply_where(df == np.inf, (x, df), norm_logpdf, t_logpdf)
8010
8017
 
8011
8018
  def _cdf(self, x, df):
8012
8019
  return sc.stdtr(df, x)
@@ -8064,8 +8071,7 @@ class t_gen(rv_continuous):
8064
8071
  - (df**-4.)/8 + 3/10*(df**-5.) + (df**-6.)/4)
8065
8072
  return h
8066
8073
 
8067
- h = _lazywhere(df >= 100, (df, ), f=asymptotic, f2=regular)
8068
- return h
8074
+ return xpx.apply_where(df >= 100, df, asymptotic, regular)
8069
8075
 
8070
8076
 
8071
8077
  t = t_gen(name='t')
@@ -8124,8 +8130,7 @@ class nct_gen(rv_continuous):
8124
8130
  return sc.nctdtr(df, nc, x)
8125
8131
 
8126
8132
  def _ppf(self, q, df, nc):
8127
- with np.errstate(over='ignore'): # see gh-17432
8128
- return scu._nct_ppf(q, df, nc)
8133
+ return sc.nctdtrit(df, nc, q)
8129
8134
 
8130
8135
  def _sf(self, x, df, nc):
8131
8136
  with np.errstate(over='ignore'): # see gh-17432
@@ -9495,10 +9500,11 @@ class recipinvgauss_gen(rv_continuous):
9495
9500
  return np.exp(self._logpdf(x, mu))
9496
9501
 
9497
9502
  def _logpdf(self, x, mu):
9498
- return _lazywhere(x > 0, (x, mu),
9499
- lambda x, mu: (-(1 - mu*x)**2.0 / (2*x*mu**2.0)
9500
- - 0.5*np.log(2*np.pi*x)),
9501
- fillvalue=-np.inf)
9503
+ return xpx.apply_where(
9504
+ x > 0, (x, mu),
9505
+ lambda x, mu: (-(1 - mu*x)**2.0 / (2*x*mu**2.0)
9506
+ - 0.5*np.log(2*np.pi*x)),
9507
+ fill_value=-np.inf)
9502
9508
 
9503
9509
  def _cdf(self, x, mu):
9504
9510
  trm1 = 1.0/mu - x
@@ -9689,16 +9695,16 @@ class skewnorm_gen(rv_continuous):
9689
9695
  return [_ShapeInfo("a", False, (-np.inf, np.inf), (False, False))]
9690
9696
 
9691
9697
  def _pdf(self, x, a):
9692
- return _lazywhere(
9693
- a == 0, (x, a), lambda x, a: _norm_pdf(x),
9694
- f2=lambda x, a: 2.*_norm_pdf(x)*_norm_cdf(a*x)
9695
- )
9698
+ return xpx.apply_where(
9699
+ a == 0, (x, a),
9700
+ lambda x, a: _norm_pdf(x),
9701
+ lambda x, a: 2.*_norm_pdf(x)*_norm_cdf(a*x))
9696
9702
 
9697
9703
  def _logpdf(self, x, a):
9698
- return _lazywhere(
9699
- a == 0, (x, a), lambda x, a: _norm_logpdf(x),
9700
- f2=lambda x, a: np.log(2)+_norm_logpdf(x)+_norm_logcdf(a*x),
9701
- )
9704
+ return xpx.apply_where(
9705
+ a == 0, (x, a),
9706
+ lambda x, a: _norm_logpdf(x),
9707
+ lambda x, a: np.log(2)+_norm_logpdf(x)+_norm_logcdf(a*x))
9702
9708
 
9703
9709
  def _cdf(self, x, a):
9704
9710
  a = np.atleast_1d(a)
@@ -9986,51 +9992,7 @@ class trapezoid_gen(rv_continuous):
9986
9992
  return 0.5 * (1.0-d+c) / (1.0+d-c) + np.log(0.5 * (1.0+d-c))
9987
9993
 
9988
9994
 
9989
- # deprecation of trapz, see #20486
9990
- deprmsg = ("`trapz` is deprecated in favour of `trapezoid` "
9991
- "and will be removed in SciPy 1.16.0.")
9992
-
9993
-
9994
- class trapz_gen(trapezoid_gen):
9995
- # override __call__ protocol from rv_generic to also
9996
- # deprecate instantiation of frozen distributions
9997
- """
9998
-
9999
- .. deprecated:: 1.14.0
10000
- `trapz` is deprecated and will be removed in SciPy 1.16.
10001
- Plese use `trapezoid` instead!
10002
- """
10003
- def __call__(self, *args, **kwds):
10004
- warnings.warn(deprmsg, DeprecationWarning, stacklevel=2)
10005
- return self.freeze(*args, **kwds)
10006
-
10007
-
10008
9995
  trapezoid = trapezoid_gen(a=0.0, b=1.0, name="trapezoid")
10009
- trapz = trapz_gen(a=0.0, b=1.0, name="trapz")
10010
-
10011
- # since the deprecated class gets intantiated upon import (and we only want to
10012
- # warn upon use), add the deprecation to each class method
10013
- _method_names = [
10014
- "cdf", "entropy", "expect", "fit", "interval", "isf", "logcdf", "logpdf",
10015
- "logsf", "mean", "median", "moment", "pdf", "ppf", "rvs", "sf", "stats",
10016
- "std", "var"
10017
- ]
10018
-
10019
-
10020
- class _DeprecationWrapper:
10021
- def __init__(self, method):
10022
- self.msg = (f"`trapz.{method}` is deprecated in favour of trapezoid.{method}. "
10023
- "Please replace all uses of the distribution class "
10024
- "`trapz` with `trapezoid`. `trapz` will be removed in SciPy 1.16.")
10025
- self.method = getattr(trapezoid, method)
10026
-
10027
- def __call__(self, *args, **kwargs):
10028
- warnings.warn(self.msg, DeprecationWarning, stacklevel=2)
10029
- return self.method(*args, **kwargs)
10030
-
10031
-
10032
- for m in _method_names:
10033
- setattr(trapz, m, _DeprecationWrapper(m))
10034
9996
 
10035
9997
 
10036
9998
  class triang_gen(rv_continuous):
@@ -10408,45 +10370,50 @@ class truncnorm_gen(rv_continuous):
10408
10370
  Returns n-th moment. Defined only if n >= 0.
10409
10371
  Function cannot broadcast due to the loop over n
10410
10372
  """
10411
- pA, pB = self._pdf(np.asarray([a, b]), a, b)
10412
- probs = [pA, -pB]
10373
+ ab = np.asarray([a, b])
10374
+ pA, pB = self._pdf(ab, a, b)
10375
+ probs = np.asarray([pA, -pB])
10376
+ cond = probs != 0
10413
10377
  moments = [0, 1]
10414
10378
  for k in range(1, n+1):
10415
10379
  # a or b might be infinite, and the corresponding pdf value
10416
10380
  # is 0 in that case, but nan is returned for the
10417
10381
  # multiplication. However, as b->infinity, pdf(b)*b**k -> 0.
10418
- # So it is safe to use _lazywhere to avoid the nan.
10419
- vals = _lazywhere(probs, [probs, [a, b]],
10420
- lambda x, y: x * y**(k-1), fillvalue=0)
10382
+ # So it is safe to use xpx.apply_where to avoid the nan.
10383
+ vals = xpx.apply_where(cond, (probs, ab),
10384
+ lambda x, y: x * y**(k-1),
10385
+ fill_value=0)
10421
10386
  mk = np.sum(vals) + (k-1) * moments[-2]
10422
10387
  moments.append(mk)
10423
10388
  return moments[-1]
10424
10389
 
10425
- return _lazywhere((n >= 0) & (a == a) & (b == b), (n, a, b),
10426
- np.vectorize(n_th_moment, otypes=[np.float64]),
10427
- np.nan)
10390
+ return xpx.apply_where((n >= 0) & (a == a) & (b == b), (n, a, b),
10391
+ np.vectorize(n_th_moment, otypes=[np.float64]),
10392
+ fill_value=np.nan)
10428
10393
 
10429
10394
  def _stats(self, a, b, moments='mv'):
10430
10395
  pA, pB = self.pdf(np.array([a, b]), a, b)
10431
10396
 
10432
- def _truncnorm_stats_scalar(a, b, pA, pB, moments):
10397
+ def _truncnorm_stats_scalar(a, b, pA, pB):
10398
+ ab = np.asarray([a, b])
10433
10399
  m1 = pA - pB
10434
10400
  mu = m1
10435
- # use _lazywhere to avoid nan (See detailed comment in _munp)
10436
- probs = [pA, -pB]
10437
- vals = _lazywhere(probs, [probs, [a, b]], lambda x, y: x*y,
10438
- fillvalue=0)
10401
+ # use xpx.apply_where to avoid nan (See detailed comment in _munp)
10402
+ probs = np.asarray([pA, -pB])
10403
+ cond = probs != 0
10404
+ vals = xpx.apply_where(cond, (probs, ab), lambda x, y: x*y,
10405
+ fill_value=0)
10439
10406
  m2 = 1 + np.sum(vals)
10440
- vals = _lazywhere(probs, [probs, [a-mu, b-mu]], lambda x, y: x*y,
10441
- fillvalue=0)
10407
+ vals = xpx.apply_where(cond, (probs, ab - mu), lambda x, y: x*y,
10408
+ fill_value=0)
10442
10409
  # mu2 = m2 - mu**2, but not as numerically stable as:
10443
10410
  # mu2 = (a-mu)*pA - (b-mu)*pB + 1
10444
10411
  mu2 = 1 + np.sum(vals)
10445
- vals = _lazywhere(probs, [probs, [a, b]], lambda x, y: x*y**2,
10446
- fillvalue=0)
10412
+ vals = xpx.apply_where(cond, (probs, ab), lambda x, y: x*y**2,
10413
+ fill_value=0)
10447
10414
  m3 = 2*m1 + np.sum(vals)
10448
- vals = _lazywhere(probs, [probs, [a, b]], lambda x, y: x*y**3,
10449
- fillvalue=0)
10415
+ vals = xpx.apply_where(cond, (probs, ab), lambda x, y: x*y**3,
10416
+ fill_value=0)
10450
10417
  m4 = 3*m2 + np.sum(vals)
10451
10418
 
10452
10419
  mu3 = m3 + m1 * (-3*m2 + 2*m1**2)
@@ -10455,9 +10422,8 @@ class truncnorm_gen(rv_continuous):
10455
10422
  g2 = mu4 / mu2**2 - 3
10456
10423
  return mu, mu2, g1, g2
10457
10424
 
10458
- _truncnorm_stats = np.vectorize(_truncnorm_stats_scalar,
10459
- excluded=('moments',))
10460
- return _truncnorm_stats(a, b, pA, pB, moments)
10425
+ _truncnorm_stats = np.vectorize(_truncnorm_stats_scalar)
10426
+ return _truncnorm_stats(a, b, pA, pB)
10461
10427
 
10462
10428
 
10463
10429
  truncnorm = truncnorm_gen(name='truncnorm', momtype=1)
@@ -10817,9 +10783,9 @@ class tukeylambda_gen(rv_continuous):
10817
10783
  return [_ShapeInfo("lam", False, (-np.inf, np.inf), (False, False))]
10818
10784
 
10819
10785
  def _get_support(self, lam):
10820
- b = _lazywhere(lam > 0, (lam,),
10821
- f=lambda lam: 1/lam,
10822
- fillvalue=np.inf)
10786
+ b = xpx.apply_where(lam > 0, lam,
10787
+ lambda lam: 1/lam,
10788
+ fill_value=np.inf)
10823
10789
  return -b, b
10824
10790
 
10825
10791
  def _pdf(self, x, lam):
@@ -11396,7 +11362,7 @@ class wrapcauchy_gen(rv_continuous):
11396
11362
  return 1 - 1/np.pi * np.arctan(cr*np.tan((2*np.pi - x)/2))
11397
11363
 
11398
11364
  cr = (1 + c)/(1 - c)
11399
- return _lazywhere(x < np.pi, (x, cr), f=f1, f2=f2)
11365
+ return xpx.apply_where(x < np.pi, (x, cr), f1, f2)
11400
11366
 
11401
11367
  def _ppf(self, q, c):
11402
11368
  val = (1.0-c)/(1.0+c)
@@ -11415,6 +11381,10 @@ class wrapcauchy_gen(rv_continuous):
11415
11381
  data = data._uncensor()
11416
11382
  return 0.5, np.min(data), np.ptp(data)/(2*np.pi)
11417
11383
 
11384
+ @inherit_docstring_from(rv_continuous)
11385
+ def rvs(self, *args, **kwds):
11386
+ rvs = super().rvs(*args, **kwds)
11387
+ return np.mod(rvs, 2*np.pi)
11418
11388
 
11419
11389
  wrapcauchy = wrapcauchy_gen(a=0.0, b=2*np.pi, name='wrapcauchy')
11420
11390
 
@@ -11487,6 +11457,15 @@ class gennorm_gen(rv_continuous):
11487
11457
  def _isf(self, x, beta):
11488
11458
  return -self._ppf(x, beta)
11489
11459
 
11460
+ def _munp(self, n, beta):
11461
+ if n == 0:
11462
+ return 1.
11463
+ if n % 2 == 0:
11464
+ c1, cn = sc.gammaln([1.0/beta, (n + 1.0)/beta])
11465
+ return np.exp(cn - c1)
11466
+ else:
11467
+ return 0.
11468
+
11490
11469
  def _stats(self, beta):
11491
11470
  c1, c3, c5 = sc.gammaln([1.0/beta, 3.0/beta, 5.0/beta])
11492
11471
  return 0., np.exp(c3 - c1), 0., np.exp(c5 + c1 - 2.0*c3) - 3.
@@ -11647,7 +11626,7 @@ class crystalball_gen(rv_continuous):
11647
11626
  return ((m/beta)**m * np.exp(-beta**2 / 2.0) *
11648
11627
  (m/beta - beta - x)**(-m))
11649
11628
 
11650
- return N * _lazywhere(x > -beta, (x, beta, m), f=rhs, f2=lhs)
11629
+ return N * xpx.apply_where(x > -beta, (x, beta, m), rhs, lhs)
11651
11630
 
11652
11631
  def _logpdf(self, x, beta, m):
11653
11632
  """
@@ -11662,7 +11641,7 @@ class crystalball_gen(rv_continuous):
11662
11641
  def lhs(x, beta, m):
11663
11642
  return m*np.log(m/beta) - beta**2/2 - m*np.log(m/beta - beta - x)
11664
11643
 
11665
- return np.log(N) + _lazywhere(x > -beta, (x, beta, m), f=rhs, f2=lhs)
11644
+ return np.log(N) + xpx.apply_where(x > -beta, (x, beta, m), rhs, lhs)
11666
11645
 
11667
11646
  def _cdf(self, x, beta, m):
11668
11647
  """
@@ -11679,7 +11658,7 @@ class crystalball_gen(rv_continuous):
11679
11658
  return ((m/beta)**m * np.exp(-beta**2 / 2.0) *
11680
11659
  (m/beta - beta - x)**(-m+1) / (m-1))
11681
11660
 
11682
- return N * _lazywhere(x > -beta, (x, beta, m), f=rhs, f2=lhs)
11661
+ return N * xpx.apply_where(x > -beta, (x, beta, m), rhs, lhs)
11683
11662
 
11684
11663
  def _sf(self, x, beta, m):
11685
11664
  """
@@ -11695,7 +11674,7 @@ class crystalball_gen(rv_continuous):
11695
11674
  # Default behavior is OK in the left tail of the SF.
11696
11675
  return 1 - self._cdf(x, beta, m)
11697
11676
 
11698
- return _lazywhere(x > -beta, (x, beta, m), f=rhs, f2=lhs)
11677
+ return xpx.apply_where(x > -beta, (x, beta, m), rhs, lhs)
11699
11678
 
11700
11679
  def _ppf(self, p, beta, m):
11701
11680
  N = 1.0 / (m/beta / (m-1) * np.exp(-beta**2 / 2.0) +
@@ -11715,7 +11694,7 @@ class crystalball_gen(rv_continuous):
11715
11694
  N = 1/(C + _norm_pdf_C * _norm_cdf(beta))
11716
11695
  return _norm_ppf(_norm_cdf(-beta) + (1/_norm_pdf_C)*(p/N - C))
11717
11696
 
11718
- return _lazywhere(p < pbeta, (p, beta, m), f=ppf_less, f2=ppf_greater)
11697
+ return xpx.apply_where(p < pbeta, (p, beta, m), ppf_less, ppf_greater)
11719
11698
 
11720
11699
  def _munp(self, n, beta, m):
11721
11700
  """
@@ -11739,9 +11718,9 @@ class crystalball_gen(rv_continuous):
11739
11718
  (m/beta)**(-m + k + 1))
11740
11719
  return A * lhs + rhs
11741
11720
 
11742
- return N * _lazywhere(n + 1 < m, (n, beta, m),
11743
- np.vectorize(n_th_moment, otypes=[np.float64]),
11744
- np.inf)
11721
+ return N * xpx.apply_where(n + 1 < m, (n, beta, m),
11722
+ np.vectorize(n_th_moment, otypes=[np.float64]),
11723
+ fill_value=np.inf)
11745
11724
 
11746
11725
 
11747
11726
  crystalball = crystalball_gen(name='crystalball', longname="A Crystalball Function")
@@ -12133,11 +12112,9 @@ class rv_histogram(rv_continuous):
12133
12112
 
12134
12113
  def _entropy(self):
12135
12114
  """Compute entropy of distribution"""
12136
- res = _lazywhere(self._hpdf[1:-1] > 0.0,
12137
- (self._hpdf[1:-1],),
12138
- np.log,
12139
- 0.0)
12140
- return -np.sum(self._hpdf[1:-1] * res * self._hbin_widths)
12115
+ hpdf = self._hpdf[1:-1]
12116
+ res = xpx.apply_where(hpdf > 0.0, hpdf, np.log, fill_value=0.0)
12117
+ return -np.sum(hpdf * res * self._hbin_widths)
12141
12118
 
12142
12119
  def _updated_ctor_param(self):
12143
12120
  """