scipy 1.15.3__cp312-cp312-macosx_14_0_arm64.whl → 1.16.0rc2__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 (628) hide show
  1. scipy/__config__.py +4 -4
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-312-darwin.so +0 -0
  4. scipy/_lib/_array_api.py +486 -161
  5. scipy/_lib/_array_api_compat_vendor.py +9 -0
  6. scipy/_lib/_bunch.py +4 -0
  7. scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
  8. scipy/_lib/_docscrape.py +1 -1
  9. scipy/_lib/_elementwise_iterative_method.py +15 -26
  10. scipy/_lib/_sparse.py +41 -0
  11. scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
  12. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  13. scipy/_lib/_testutils.py +6 -2
  14. scipy/_lib/_util.py +222 -125
  15. scipy/_lib/array_api_compat/__init__.py +4 -4
  16. scipy/_lib/array_api_compat/_internal.py +19 -6
  17. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  18. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  19. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  20. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  21. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  22. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  23. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  24. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  25. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  26. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  27. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  28. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  29. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  30. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  31. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  32. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  33. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  34. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  35. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  36. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  37. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  38. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  39. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  40. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  41. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  42. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  43. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  44. scipy/_lib/array_api_extra/__init__.py +26 -3
  45. scipy/_lib/array_api_extra/_delegation.py +171 -0
  46. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  47. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  48. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  49. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  50. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  51. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  52. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  58. scipy/_lib/array_api_extra/testing.py +359 -0
  59. scipy/_lib/decorator.py +2 -2
  60. scipy/_lib/doccer.py +1 -7
  61. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  62. scipy/_lib/pyprima/__init__.py +212 -0
  63. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  64. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  65. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  66. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  67. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  68. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  69. scipy/_lib/pyprima/cobyla/update.py +289 -0
  70. scipy/_lib/pyprima/common/__init__.py +0 -0
  71. scipy/_lib/pyprima/common/_bounds.py +34 -0
  72. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  73. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  74. scipy/_lib/pyprima/common/_project.py +173 -0
  75. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  76. scipy/_lib/pyprima/common/consts.py +47 -0
  77. scipy/_lib/pyprima/common/evaluate.py +99 -0
  78. scipy/_lib/pyprima/common/history.py +38 -0
  79. scipy/_lib/pyprima/common/infos.py +30 -0
  80. scipy/_lib/pyprima/common/linalg.py +435 -0
  81. scipy/_lib/pyprima/common/message.py +290 -0
  82. scipy/_lib/pyprima/common/powalg.py +131 -0
  83. scipy/_lib/pyprima/common/preproc.py +277 -0
  84. scipy/_lib/pyprima/common/present.py +5 -0
  85. scipy/_lib/pyprima/common/ratio.py +54 -0
  86. scipy/_lib/pyprima/common/redrho.py +47 -0
  87. scipy/_lib/pyprima/common/selectx.py +296 -0
  88. scipy/_lib/tests/test__util.py +105 -121
  89. scipy/_lib/tests/test_array_api.py +166 -35
  90. scipy/_lib/tests/test_bunch.py +7 -0
  91. scipy/_lib/tests/test_ccallback.py +2 -10
  92. scipy/_lib/tests/test_public_api.py +13 -0
  93. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  94. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  95. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  96. scipy/cluster/hierarchy.py +393 -223
  97. scipy/cluster/tests/test_hierarchy.py +273 -335
  98. scipy/cluster/tests/test_vq.py +45 -61
  99. scipy/cluster/vq.py +39 -35
  100. scipy/conftest.py +263 -157
  101. scipy/constants/_constants.py +4 -1
  102. scipy/constants/tests/test_codata.py +2 -2
  103. scipy/constants/tests/test_constants.py +11 -18
  104. scipy/datasets/_download_all.py +15 -1
  105. scipy/datasets/_fetchers.py +7 -1
  106. scipy/datasets/_utils.py +1 -1
  107. scipy/differentiate/_differentiate.py +25 -25
  108. scipy/differentiate/tests/test_differentiate.py +24 -25
  109. scipy/fft/_basic.py +20 -0
  110. scipy/fft/_helper.py +3 -34
  111. scipy/fft/_pocketfft/helper.py +29 -1
  112. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  113. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  114. scipy/fft/_realtransforms.py +13 -0
  115. scipy/fft/tests/test_basic.py +27 -25
  116. scipy/fft/tests/test_fftlog.py +16 -7
  117. scipy/fft/tests/test_helper.py +18 -34
  118. scipy/fft/tests/test_real_transforms.py +8 -10
  119. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  120. scipy/fftpack/tests/test_basic.py +2 -4
  121. scipy/fftpack/tests/test_real_transforms.py +8 -9
  122. scipy/integrate/_bvp.py +9 -3
  123. scipy/integrate/_cubature.py +3 -2
  124. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  125. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  126. scipy/integrate/_ode.py +9 -2
  127. scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
  128. scipy/integrate/_quad_vec.py +21 -29
  129. scipy/integrate/_quadpack.cpython-312-darwin.so +0 -0
  130. scipy/integrate/_quadpack_py.py +11 -7
  131. scipy/integrate/_quadrature.py +3 -3
  132. scipy/integrate/_rules/_base.py +2 -2
  133. scipy/integrate/_tanhsinh.py +48 -47
  134. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  135. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  136. scipy/integrate/tests/test__quad_vec.py +0 -6
  137. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  138. scipy/integrate/tests/test_cubature.py +21 -35
  139. scipy/integrate/tests/test_quadrature.py +6 -8
  140. scipy/integrate/tests/test_tanhsinh.py +56 -48
  141. scipy/interpolate/__init__.py +70 -58
  142. scipy/interpolate/_bary_rational.py +22 -22
  143. scipy/interpolate/_bsplines.py +119 -66
  144. scipy/interpolate/_cubic.py +65 -50
  145. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  146. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  147. scipy/interpolate/_fitpack.cpython-312-darwin.so +0 -0
  148. scipy/interpolate/_fitpack2.py +9 -6
  149. scipy/interpolate/_fitpack_impl.py +32 -26
  150. scipy/interpolate/_fitpack_repro.py +23 -19
  151. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  152. scipy/interpolate/_interpolate.py +30 -12
  153. scipy/interpolate/_ndbspline.py +13 -18
  154. scipy/interpolate/_ndgriddata.py +5 -8
  155. scipy/interpolate/_polyint.py +95 -31
  156. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  157. scipy/interpolate/_rbf.py +2 -2
  158. scipy/interpolate/_rbfinterp.py +1 -1
  159. scipy/interpolate/_rbfinterp_pythran.cpython-312-darwin.so +0 -0
  160. scipy/interpolate/_rgi.py +31 -26
  161. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  162. scipy/interpolate/dfitpack.py +0 -20
  163. scipy/interpolate/interpnd.py +1 -2
  164. scipy/interpolate/tests/test_bary_rational.py +2 -2
  165. scipy/interpolate/tests/test_bsplines.py +97 -1
  166. scipy/interpolate/tests/test_fitpack2.py +39 -1
  167. scipy/interpolate/tests/test_interpnd.py +32 -20
  168. scipy/interpolate/tests/test_interpolate.py +48 -4
  169. scipy/interpolate/tests/test_rgi.py +2 -1
  170. scipy/io/_fast_matrix_market/__init__.py +2 -0
  171. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  172. scipy/io/_harwell_boeing/hb.py +7 -11
  173. scipy/io/_idl.py +5 -7
  174. scipy/io/_netcdf.py +15 -5
  175. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  176. scipy/io/arff/tests/test_arffread.py +3 -3
  177. scipy/io/matlab/__init__.py +5 -3
  178. scipy/io/matlab/_mio.py +4 -1
  179. scipy/io/matlab/_mio5.py +19 -13
  180. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  181. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  182. scipy/io/matlab/_miobase.py +4 -1
  183. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  184. scipy/io/matlab/tests/test_mio.py +46 -18
  185. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  186. scipy/io/tests/test_mmio.py +7 -1
  187. scipy/io/tests/test_wavfile.py +41 -0
  188. scipy/io/wavfile.py +57 -10
  189. scipy/linalg/_basic.py +113 -86
  190. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  191. scipy/linalg/_decomp.py +22 -9
  192. scipy/linalg/_decomp_cholesky.py +28 -13
  193. scipy/linalg/_decomp_cossin.py +45 -30
  194. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  195. scipy/linalg/_decomp_ldl.py +4 -1
  196. scipy/linalg/_decomp_lu.py +18 -6
  197. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  198. scipy/linalg/_decomp_polar.py +2 -0
  199. scipy/linalg/_decomp_qr.py +6 -2
  200. scipy/linalg/_decomp_qz.py +3 -0
  201. scipy/linalg/_decomp_schur.py +3 -1
  202. scipy/linalg/_decomp_svd.py +13 -2
  203. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  204. scipy/linalg/_expm_frechet.py +4 -0
  205. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  206. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  207. scipy/linalg/_linalg_pythran.cpython-312-darwin.so +0 -0
  208. scipy/linalg/_matfuncs.py +187 -4
  209. scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
  210. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  211. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  212. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  213. scipy/linalg/_procrustes.py +2 -0
  214. scipy/linalg/_sketches.py +17 -6
  215. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  216. scipy/linalg/_solvers.py +7 -2
  217. scipy/linalg/_special_matrices.py +26 -36
  218. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  219. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  220. scipy/linalg/lapack.py +22 -2
  221. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  222. scipy/linalg/tests/test_basic.py +31 -16
  223. scipy/linalg/tests/test_batch.py +588 -0
  224. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  225. scipy/linalg/tests/test_decomp.py +40 -3
  226. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  227. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  228. scipy/linalg/tests/test_lapack.py +115 -7
  229. scipy/linalg/tests/test_matfuncs.py +157 -102
  230. scipy/linalg/tests/test_procrustes.py +0 -7
  231. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  232. scipy/linalg/tests/test_special_matrices.py +1 -5
  233. scipy/ndimage/__init__.py +1 -0
  234. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  235. scipy/ndimage/_delegators.py +8 -2
  236. scipy/ndimage/_filters.py +453 -5
  237. scipy/ndimage/_interpolation.py +36 -6
  238. scipy/ndimage/_measurements.py +4 -2
  239. scipy/ndimage/_morphology.py +5 -0
  240. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  241. scipy/ndimage/_ni_docstrings.py +5 -1
  242. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  243. scipy/ndimage/_ni_support.py +1 -5
  244. scipy/ndimage/_rank_filter_1d.cpython-312-darwin.so +0 -0
  245. scipy/ndimage/_support_alternative_backends.py +18 -6
  246. scipy/ndimage/tests/test_filters.py +370 -259
  247. scipy/ndimage/tests/test_fourier.py +7 -9
  248. scipy/ndimage/tests/test_interpolation.py +68 -61
  249. scipy/ndimage/tests/test_measurements.py +18 -35
  250. scipy/ndimage/tests/test_morphology.py +143 -131
  251. scipy/ndimage/tests/test_splines.py +1 -3
  252. scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
  253. scipy/optimize/_basinhopping.py +13 -7
  254. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  255. scipy/optimize/_bracket.py +17 -24
  256. scipy/optimize/_chandrupatla.py +9 -10
  257. scipy/optimize/_cobyla_py.py +104 -123
  258. scipy/optimize/_constraints.py +14 -10
  259. scipy/optimize/_differentiable_functions.py +371 -230
  260. scipy/optimize/_differentialevolution.py +4 -3
  261. scipy/optimize/_direct.cpython-312-darwin.so +0 -0
  262. scipy/optimize/_dual_annealing.py +1 -1
  263. scipy/optimize/_elementwise.py +1 -4
  264. scipy/optimize/_group_columns.cpython-312-darwin.so +0 -0
  265. scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
  266. scipy/optimize/_lbfgsb_py.py +57 -16
  267. scipy/optimize/_linprog_doc.py +2 -2
  268. scipy/optimize/_linprog_highs.py +2 -2
  269. scipy/optimize/_linprog_ip.py +25 -10
  270. scipy/optimize/_linprog_util.py +14 -16
  271. scipy/optimize/_lsap.cpython-312-darwin.so +0 -0
  272. scipy/optimize/_lsq/common.py +3 -3
  273. scipy/optimize/_lsq/dogbox.py +16 -2
  274. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  275. scipy/optimize/_lsq/least_squares.py +198 -126
  276. scipy/optimize/_lsq/lsq_linear.py +6 -6
  277. scipy/optimize/_lsq/trf.py +35 -8
  278. scipy/optimize/_milp.py +3 -1
  279. scipy/optimize/_minimize.py +105 -36
  280. scipy/optimize/_minpack.cpython-312-darwin.so +0 -0
  281. scipy/optimize/_minpack_py.py +21 -14
  282. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  283. scipy/optimize/_nnls.py +20 -21
  284. scipy/optimize/_nonlin.py +34 -3
  285. scipy/optimize/_numdiff.py +288 -110
  286. scipy/optimize/_optimize.py +86 -48
  287. scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
  288. scipy/optimize/_remove_redundancy.py +5 -5
  289. scipy/optimize/_root_scalar.py +1 -1
  290. scipy/optimize/_shgo.py +6 -0
  291. scipy/optimize/_shgo_lib/_complex.py +1 -1
  292. scipy/optimize/_slsqp_py.py +216 -124
  293. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  294. scipy/optimize/_spectral.py +1 -1
  295. scipy/optimize/_tnc.py +8 -1
  296. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  297. scipy/optimize/_trustregion.py +20 -6
  298. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  299. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  300. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  301. scipy/optimize/_trustregion_constr/projections.py +12 -8
  302. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  303. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  304. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  305. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  306. scipy/optimize/_trustregion_exact.py +0 -1
  307. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  308. scipy/optimize/_zeros_py.py +97 -17
  309. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  310. scipy/optimize/slsqp.py +0 -1
  311. scipy/optimize/tests/test__basinhopping.py +1 -1
  312. scipy/optimize/tests/test__differential_evolution.py +4 -4
  313. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  314. scipy/optimize/tests/test__numdiff.py +66 -22
  315. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  316. scipy/optimize/tests/test__shgo.py +9 -1
  317. scipy/optimize/tests/test_bracket.py +36 -46
  318. scipy/optimize/tests/test_chandrupatla.py +133 -135
  319. scipy/optimize/tests/test_cobyla.py +74 -45
  320. scipy/optimize/tests/test_constraints.py +1 -1
  321. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  322. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  323. scipy/optimize/tests/test_least_squares.py +125 -13
  324. scipy/optimize/tests/test_linear_assignment.py +3 -3
  325. scipy/optimize/tests/test_linprog.py +3 -3
  326. scipy/optimize/tests/test_lsq_linear.py +6 -6
  327. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  328. scipy/optimize/tests/test_minpack.py +4 -4
  329. scipy/optimize/tests/test_nnls.py +43 -3
  330. scipy/optimize/tests/test_nonlin.py +36 -0
  331. scipy/optimize/tests/test_optimize.py +95 -17
  332. scipy/optimize/tests/test_slsqp.py +36 -4
  333. scipy/optimize/tests/test_zeros.py +34 -1
  334. scipy/signal/__init__.py +12 -23
  335. scipy/signal/_delegators.py +568 -0
  336. scipy/signal/_filter_design.py +459 -241
  337. scipy/signal/_fir_filter_design.py +262 -90
  338. scipy/signal/_lti_conversion.py +3 -2
  339. scipy/signal/_ltisys.py +118 -91
  340. scipy/signal/_max_len_seq_inner.cpython-312-darwin.so +0 -0
  341. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  342. scipy/signal/_polyutils.py +172 -0
  343. scipy/signal/_short_time_fft.py +519 -70
  344. scipy/signal/_signal_api.py +30 -0
  345. scipy/signal/_signaltools.py +719 -399
  346. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  347. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  348. scipy/signal/_spectral_py.py +230 -50
  349. scipy/signal/_spline.cpython-312-darwin.so +0 -0
  350. scipy/signal/_spline_filters.py +108 -68
  351. scipy/signal/_support_alternative_backends.py +73 -0
  352. scipy/signal/_upfirdn.py +4 -1
  353. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  354. scipy/signal/_waveforms.py +2 -11
  355. scipy/signal/_wavelets.py +1 -1
  356. scipy/signal/fir_filter_design.py +1 -0
  357. scipy/signal/spline.py +4 -11
  358. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  359. scipy/signal/tests/test_bsplines.py +114 -79
  360. scipy/signal/tests/test_cont2discrete.py +9 -2
  361. scipy/signal/tests/test_filter_design.py +721 -481
  362. scipy/signal/tests/test_fir_filter_design.py +332 -140
  363. scipy/signal/tests/test_savitzky_golay.py +4 -3
  364. scipy/signal/tests/test_short_time_fft.py +221 -3
  365. scipy/signal/tests/test_signaltools.py +2144 -1348
  366. scipy/signal/tests/test_spectral.py +50 -6
  367. scipy/signal/tests/test_splines.py +161 -96
  368. scipy/signal/tests/test_upfirdn.py +84 -50
  369. scipy/signal/tests/test_waveforms.py +20 -0
  370. scipy/signal/tests/test_windows.py +607 -466
  371. scipy/signal/windows/_windows.py +287 -148
  372. scipy/sparse/__init__.py +23 -4
  373. scipy/sparse/_base.py +270 -108
  374. scipy/sparse/_bsr.py +7 -4
  375. scipy/sparse/_compressed.py +59 -231
  376. scipy/sparse/_construct.py +90 -38
  377. scipy/sparse/_coo.py +115 -181
  378. scipy/sparse/_csc.py +4 -4
  379. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  380. scipy/sparse/_csr.py +2 -2
  381. scipy/sparse/_data.py +48 -48
  382. scipy/sparse/_dia.py +105 -18
  383. scipy/sparse/_dok.py +0 -23
  384. scipy/sparse/_index.py +4 -4
  385. scipy/sparse/_matrix.py +23 -0
  386. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  387. scipy/sparse/_sputils.py +37 -22
  388. scipy/sparse/base.py +0 -9
  389. scipy/sparse/bsr.py +0 -14
  390. scipy/sparse/compressed.py +0 -23
  391. scipy/sparse/construct.py +0 -6
  392. scipy/sparse/coo.py +0 -14
  393. scipy/sparse/csc.py +0 -3
  394. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  395. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  396. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  397. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  398. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  399. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  400. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  401. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  402. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  403. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  404. scipy/sparse/csr.py +0 -5
  405. scipy/sparse/data.py +1 -6
  406. scipy/sparse/dia.py +0 -7
  407. scipy/sparse/dok.py +0 -10
  408. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  409. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  410. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  411. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  412. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  413. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  414. scipy/sparse/linalg/_interface.py +17 -18
  415. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  416. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  417. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  418. scipy/sparse/linalg/_isolve/minres.py +5 -5
  419. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  420. scipy/sparse/linalg/_isolve/utils.py +2 -8
  421. scipy/sparse/linalg/_matfuncs.py +1 -1
  422. scipy/sparse/linalg/_norm.py +1 -1
  423. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  424. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  425. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  426. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  427. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  428. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  429. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  430. scipy/sparse/tests/test_base.py +214 -42
  431. scipy/sparse/tests/test_common1d.py +7 -7
  432. scipy/sparse/tests/test_construct.py +1 -1
  433. scipy/sparse/tests/test_coo.py +272 -4
  434. scipy/sparse/tests/test_sparsetools.py +5 -0
  435. scipy/sparse/tests/test_sputils.py +36 -7
  436. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  437. scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
  438. scipy/spatial/_distance_wrap.cpython-312-darwin.so +0 -0
  439. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  440. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  441. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  442. scipy/spatial/distance.py +49 -42
  443. scipy/spatial/tests/test_distance.py +15 -1
  444. scipy/spatial/tests/test_kdtree.py +1 -0
  445. scipy/spatial/tests/test_qhull.py +7 -2
  446. scipy/spatial/transform/__init__.py +5 -3
  447. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  448. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  449. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  450. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  451. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  452. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  453. scipy/special/__init__.py +1 -47
  454. scipy/special/_add_newdocs.py +34 -772
  455. scipy/special/_basic.py +22 -25
  456. scipy/special/_comb.cpython-312-darwin.so +0 -0
  457. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  458. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  459. scipy/special/_logsumexp.py +67 -58
  460. scipy/special/_orthogonal.pyi +1 -1
  461. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  462. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  463. scipy/special/_spherical_bessel.py +4 -4
  464. scipy/special/_support_alternative_backends.py +212 -119
  465. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  466. scipy/special/_testutils.py +4 -4
  467. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  468. scipy/special/_ufuncs.pyi +1 -0
  469. scipy/special/_ufuncs.pyx +215 -1400
  470. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  471. scipy/special/_ufuncs_cxx.pxd +2 -15
  472. scipy/special/_ufuncs_cxx.pyx +5 -44
  473. scipy/special/_ufuncs_cxx_defs.h +2 -16
  474. scipy/special/_ufuncs_defs.h +0 -8
  475. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  476. scipy/special/cython_special.pxd +1 -1
  477. scipy/special/tests/_cython_examples/meson.build +10 -1
  478. scipy/special/tests/test_basic.py +153 -20
  479. scipy/special/tests/test_boost_ufuncs.py +3 -0
  480. scipy/special/tests/test_cdflib.py +35 -11
  481. scipy/special/tests/test_gammainc.py +16 -0
  482. scipy/special/tests/test_hyp2f1.py +2 -2
  483. scipy/special/tests/test_log1mexp.py +85 -0
  484. scipy/special/tests/test_logsumexp.py +206 -64
  485. scipy/special/tests/test_mpmath.py +1 -0
  486. scipy/special/tests/test_nan_inputs.py +1 -1
  487. scipy/special/tests/test_orthogonal.py +17 -18
  488. scipy/special/tests/test_sf_error.py +3 -2
  489. scipy/special/tests/test_sph_harm.py +6 -7
  490. scipy/special/tests/test_support_alternative_backends.py +211 -76
  491. scipy/stats/__init__.py +4 -1
  492. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  493. scipy/stats/_axis_nan_policy.py +5 -12
  494. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  495. scipy/stats/_continued_fraction.py +387 -0
  496. scipy/stats/_continuous_distns.py +277 -310
  497. scipy/stats/_correlation.py +1 -1
  498. scipy/stats/_covariance.py +6 -3
  499. scipy/stats/_discrete_distns.py +39 -32
  500. scipy/stats/_distn_infrastructure.py +39 -12
  501. scipy/stats/_distribution_infrastructure.py +900 -238
  502. scipy/stats/_entropy.py +9 -10
  503. scipy/{_lib → stats}/_finite_differences.py +1 -1
  504. scipy/stats/_hypotests.py +83 -50
  505. scipy/stats/_kde.py +53 -49
  506. scipy/stats/_ksstats.py +1 -1
  507. scipy/stats/_levy_stable/__init__.py +7 -15
  508. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  509. scipy/stats/_morestats.py +118 -73
  510. scipy/stats/_mstats_basic.py +13 -17
  511. scipy/stats/_mstats_extras.py +8 -8
  512. scipy/stats/_multivariate.py +89 -113
  513. scipy/stats/_new_distributions.py +97 -20
  514. scipy/stats/_page_trend_test.py +12 -5
  515. scipy/stats/_probability_distribution.py +265 -43
  516. scipy/stats/_qmc.py +14 -9
  517. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  518. scipy/stats/_qmvnt.py +16 -95
  519. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  520. scipy/stats/_quantile.py +335 -0
  521. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  522. scipy/stats/_resampling.py +4 -29
  523. scipy/stats/_sampling.py +1 -1
  524. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  525. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  526. scipy/stats/_stats_mstats_common.py +21 -2
  527. scipy/stats/_stats_py.py +550 -476
  528. scipy/stats/_stats_pythran.cpython-312-darwin.so +0 -0
  529. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  530. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  531. scipy/stats/_variation.py +6 -8
  532. scipy/stats/_wilcoxon.py +13 -7
  533. scipy/stats/tests/common_tests.py +6 -4
  534. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  535. scipy/stats/tests/test_continued_fraction.py +173 -0
  536. scipy/stats/tests/test_continuous.py +379 -60
  537. scipy/stats/tests/test_continuous_basic.py +18 -12
  538. scipy/stats/tests/test_discrete_basic.py +14 -8
  539. scipy/stats/tests/test_discrete_distns.py +16 -16
  540. scipy/stats/tests/test_distributions.py +95 -75
  541. scipy/stats/tests/test_entropy.py +40 -48
  542. scipy/stats/tests/test_fit.py +4 -3
  543. scipy/stats/tests/test_hypotests.py +153 -24
  544. scipy/stats/tests/test_kdeoth.py +109 -41
  545. scipy/stats/tests/test_marray.py +289 -0
  546. scipy/stats/tests/test_morestats.py +79 -47
  547. scipy/stats/tests/test_mstats_basic.py +3 -3
  548. scipy/stats/tests/test_multivariate.py +434 -83
  549. scipy/stats/tests/test_qmc.py +13 -10
  550. scipy/stats/tests/test_quantile.py +199 -0
  551. scipy/stats/tests/test_rank.py +119 -112
  552. scipy/stats/tests/test_resampling.py +47 -56
  553. scipy/stats/tests/test_sampling.py +9 -4
  554. scipy/stats/tests/test_stats.py +799 -939
  555. scipy/stats/tests/test_variation.py +8 -6
  556. scipy/version.py +2 -2
  557. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  558. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  559. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +560 -567
  560. scipy-1.16.0rc2.dist-info/WHEEL +6 -0
  561. scipy/_lib/array_api_extra/_funcs.py +0 -484
  562. scipy/_lib/array_api_extra/_typing.py +0 -8
  563. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  564. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  565. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  566. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  567. scipy/spatial/qhull_src/COPYING.txt +0 -38
  568. scipy/special/libsf_error_state.dylib +0 -0
  569. scipy/special/tests/test_log_softmax.py +0 -109
  570. scipy/special/tests/test_xsf_cuda.py +0 -114
  571. scipy/special/xsf/binom.h +0 -89
  572. scipy/special/xsf/cdflib.h +0 -100
  573. scipy/special/xsf/cephes/airy.h +0 -307
  574. scipy/special/xsf/cephes/besselpoly.h +0 -51
  575. scipy/special/xsf/cephes/beta.h +0 -257
  576. scipy/special/xsf/cephes/cbrt.h +0 -131
  577. scipy/special/xsf/cephes/chbevl.h +0 -85
  578. scipy/special/xsf/cephes/chdtr.h +0 -193
  579. scipy/special/xsf/cephes/const.h +0 -87
  580. scipy/special/xsf/cephes/ellie.h +0 -293
  581. scipy/special/xsf/cephes/ellik.h +0 -251
  582. scipy/special/xsf/cephes/ellpe.h +0 -107
  583. scipy/special/xsf/cephes/ellpk.h +0 -117
  584. scipy/special/xsf/cephes/expn.h +0 -260
  585. scipy/special/xsf/cephes/gamma.h +0 -398
  586. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  587. scipy/special/xsf/cephes/hyperg.h +0 -361
  588. scipy/special/xsf/cephes/i0.h +0 -149
  589. scipy/special/xsf/cephes/i1.h +0 -158
  590. scipy/special/xsf/cephes/igam.h +0 -421
  591. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  592. scipy/special/xsf/cephes/igami.h +0 -313
  593. scipy/special/xsf/cephes/j0.h +0 -225
  594. scipy/special/xsf/cephes/j1.h +0 -198
  595. scipy/special/xsf/cephes/jv.h +0 -715
  596. scipy/special/xsf/cephes/k0.h +0 -164
  597. scipy/special/xsf/cephes/k1.h +0 -163
  598. scipy/special/xsf/cephes/kn.h +0 -243
  599. scipy/special/xsf/cephes/lanczos.h +0 -112
  600. scipy/special/xsf/cephes/ndtr.h +0 -275
  601. scipy/special/xsf/cephes/poch.h +0 -85
  602. scipy/special/xsf/cephes/polevl.h +0 -167
  603. scipy/special/xsf/cephes/psi.h +0 -194
  604. scipy/special/xsf/cephes/rgamma.h +0 -111
  605. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  606. scipy/special/xsf/cephes/shichi.h +0 -248
  607. scipy/special/xsf/cephes/sici.h +0 -224
  608. scipy/special/xsf/cephes/sindg.h +0 -221
  609. scipy/special/xsf/cephes/tandg.h +0 -139
  610. scipy/special/xsf/cephes/trig.h +0 -58
  611. scipy/special/xsf/cephes/unity.h +0 -186
  612. scipy/special/xsf/cephes/zeta.h +0 -172
  613. scipy/special/xsf/config.h +0 -304
  614. scipy/special/xsf/digamma.h +0 -205
  615. scipy/special/xsf/error.h +0 -57
  616. scipy/special/xsf/evalpoly.h +0 -47
  617. scipy/special/xsf/expint.h +0 -266
  618. scipy/special/xsf/hyp2f1.h +0 -694
  619. scipy/special/xsf/iv_ratio.h +0 -173
  620. scipy/special/xsf/lambertw.h +0 -150
  621. scipy/special/xsf/loggamma.h +0 -163
  622. scipy/special/xsf/sici.h +0 -200
  623. scipy/special/xsf/tools.h +0 -427
  624. scipy/special/xsf/trig.h +0 -164
  625. scipy/special/xsf/wright_bessel.h +0 -843
  626. scipy/special/xsf/zlog1.h +0 -35
  627. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  628. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -2,6 +2,7 @@
2
2
  # Author: Joris Vankerschaver 2013
3
3
  #
4
4
  import math
5
+ import warnings
5
6
  import threading
6
7
  import numpy as np
7
8
  import scipy.linalg
@@ -9,12 +10,13 @@ from scipy._lib import doccer
9
10
  from scipy.special import (gammaln, psi, multigammaln, xlogy, entr, betaln,
10
11
  ive, loggamma)
11
12
  from scipy import special
12
- from scipy._lib._util import check_random_state, _lazywhere
13
+ import scipy._lib.array_api_extra as xpx
14
+ from scipy._lib._util import check_random_state
13
15
  from scipy.linalg.blas import drot, get_blas_funcs
14
16
  from ._continuous_distns import norm, invgamma
15
17
  from ._discrete_distns import binom
16
- from . import _mvn, _covariance, _rcont
17
- from ._qmvnt import _qmvt
18
+ from . import _covariance, _rcont
19
+ from ._qmvnt import _qmvt, _qmvn, _qauto
18
20
  from ._morestats import directional_stats
19
21
  from scipy.optimize import root_scalar
20
22
 
@@ -393,14 +395,14 @@ class multivariate_normal_gen(multi_rv_generic):
393
395
  super().__init__(seed)
394
396
  self.__doc__ = doccer.docformat(self.__doc__, mvn_docdict_params)
395
397
 
396
- def __call__(self, mean=None, cov=1, allow_singular=False, seed=None):
398
+ def __call__(self, mean=None, cov=1, allow_singular=False, seed=None, **kwds):
397
399
  """Create a frozen multivariate normal distribution.
398
400
 
399
401
  See `multivariate_normal_frozen` for more information.
400
402
  """
401
403
  return multivariate_normal_frozen(mean, cov,
402
404
  allow_singular=allow_singular,
403
- seed=seed)
405
+ seed=seed, **kwds)
404
406
 
405
407
  def _process_parameters(self, mean, cov, allow_singular=True):
406
408
  """
@@ -472,8 +474,7 @@ class multivariate_normal_gen(multi_rv_generic):
472
474
  cov = cov.reshape(1, 1)
473
475
 
474
476
  if mean.ndim != 1 or mean.shape[0] != dim:
475
- raise ValueError("Array 'mean' must be a vector of length %d." %
476
- dim)
477
+ raise ValueError(f"Array 'mean' must be a vector of length {dim}.")
477
478
  if cov.ndim == 0:
478
479
  cov = cov * np.eye(dim)
479
480
  elif cov.ndim == 1:
@@ -484,13 +485,12 @@ class multivariate_normal_gen(multi_rv_generic):
484
485
  msg = ("Array 'cov' must be square if it is two dimensional,"
485
486
  f" but cov.shape = {str(cov.shape)}.")
486
487
  else:
487
- msg = ("Dimension mismatch: array 'cov' is of shape %s,"
488
- " but 'mean' is a vector of length %d.")
489
- msg = msg % (str(cov.shape), len(mean))
488
+ msg = (f"Dimension mismatch: array 'cov' is of shape {cov.shape}, "
489
+ f"but 'mean' is a vector of length {len(mean)}.")
490
490
  raise ValueError(msg)
491
491
  elif cov.ndim > 2:
492
- raise ValueError("Array 'cov' must be at most two-dimensional,"
493
- " but cov.ndim = %d" % cov.ndim)
492
+ raise ValueError(f"Array 'cov' must be at most two-dimensional, "
493
+ f"but cov.ndim = {cov.ndim}")
494
494
 
495
495
  return dim, mean, cov
496
496
 
@@ -594,7 +594,7 @@ class multivariate_normal_gen(multi_rv_generic):
594
594
  out[out_of_bounds] = 0.0
595
595
  return _squeeze_output(out)
596
596
 
597
- def _cdf(self, x, mean, cov, maxpts, abseps, releps, lower_limit):
597
+ def _cdf(self, x, mean, cov, maxpts, abseps, releps, lower_limit, rng):
598
598
  """Multivariate normal cumulative distribution function.
599
599
 
600
600
  Parameters
@@ -614,6 +614,9 @@ class multivariate_normal_gen(multi_rv_generic):
614
614
  lower_limit : array_like, optional
615
615
  Lower limit of integration of the cumulative distribution function.
616
616
  Default is negative infinity. Must be broadcastable with `x`.
617
+ rng : Generator
618
+ an instance of ``np.random.Generator``, which is used internally
619
+ for QMC integration.
617
620
 
618
621
  Notes
619
622
  -----
@@ -631,6 +634,7 @@ class multivariate_normal_gen(multi_rv_generic):
631
634
  # ensuring that lower bounds are indeed lower when passed, then
632
635
  # set signs of resulting CDF manually.
633
636
  b, a = np.broadcast_arrays(x, lower)
637
+ b, a = b - mean, a - mean # _qmvn only accepts zero mean
634
638
  i_swap = b < a
635
639
  signs = (-1)**(i_swap.sum(axis=-1)) # odd # of swaps -> negative
636
640
  a, b = a.copy(), b.copy()
@@ -638,17 +642,19 @@ class multivariate_normal_gen(multi_rv_generic):
638
642
  n = x.shape[-1]
639
643
  limits = np.concatenate((a, b), axis=-1)
640
644
 
641
- # mvnun expects 1-d arguments, so process points sequentially
645
+ # qmvn expects 1-d arguments, so process points sequentially
646
+ # XXX: if cov.ndim == 2 and limits.ndim == 1, can avoid apply_along_axis
642
647
  def func1d(limits):
643
- with MVN_LOCK:
644
- return _mvn.mvnun(limits[:n], limits[n:], mean, cov,
645
- maxpts, abseps, releps)[0]
648
+ # res0 = _qmvn(maxpts, cov, limits[:n], limits[n:], rng)[0]
649
+ res = _qauto(_qmvn, cov, limits[:n], limits[n:],
650
+ rng, error=abseps, limit=maxpts, n_batches=10)
651
+ return np.squeeze(res[0])
646
652
 
647
653
  out = np.apply_along_axis(func1d, -1, limits) * signs
648
654
  return _squeeze_output(out)
649
655
 
650
656
  def logcdf(self, x, mean=None, cov=1, allow_singular=False, maxpts=None,
651
- abseps=1e-5, releps=1e-5, *, lower_limit=None):
657
+ abseps=1e-5, releps=1e-5, *, lower_limit=None, rng=None):
652
658
  """Log of the multivariate normal cumulative distribution function.
653
659
 
654
660
  Parameters
@@ -666,6 +672,9 @@ class multivariate_normal_gen(multi_rv_generic):
666
672
  lower_limit : array_like, optional
667
673
  Lower limit of integration of the cumulative distribution function.
668
674
  Default is negative infinity. Must be broadcastable with `x`.
675
+ rng : Generator, optional
676
+ an instance of ``np.random.Generator``, which is used internally
677
+ for QMC integration.
669
678
 
670
679
  Returns
671
680
  -------
@@ -685,7 +694,9 @@ class multivariate_normal_gen(multi_rv_generic):
685
694
  x = self._process_quantiles(x, dim)
686
695
  if not maxpts:
687
696
  maxpts = 1000000 * dim
688
- cdf = self._cdf(x, mean, cov, maxpts, abseps, releps, lower_limit)
697
+
698
+ rng = self._get_random_state(rng)
699
+ cdf = self._cdf(x, mean, cov, maxpts, abseps, releps, lower_limit, rng)
689
700
  # the log of a negative real is complex, and cdf can be negative
690
701
  # if lower limit is greater than upper limit
691
702
  cdf = cdf + 0j if np.any(cdf < 0) else cdf
@@ -693,7 +704,7 @@ class multivariate_normal_gen(multi_rv_generic):
693
704
  return out
694
705
 
695
706
  def cdf(self, x, mean=None, cov=1, allow_singular=False, maxpts=None,
696
- abseps=1e-5, releps=1e-5, *, lower_limit=None):
707
+ abseps=1e-5, releps=1e-5, *, lower_limit=None, rng=None):
697
708
  """Multivariate normal cumulative distribution function.
698
709
 
699
710
  Parameters
@@ -711,6 +722,9 @@ class multivariate_normal_gen(multi_rv_generic):
711
722
  lower_limit : array_like, optional
712
723
  Lower limit of integration of the cumulative distribution function.
713
724
  Default is negative infinity. Must be broadcastable with `x`.
725
+ rng : Generator, optional
726
+ an instance of ``np.random.Generator``, which is used internally
727
+ for QMC integration.
714
728
 
715
729
  Returns
716
730
  -------
@@ -730,7 +744,8 @@ class multivariate_normal_gen(multi_rv_generic):
730
744
  x = self._process_quantiles(x, dim)
731
745
  if not maxpts:
732
746
  maxpts = 1000000 * dim
733
- out = self._cdf(x, mean, cov, maxpts, abseps, releps, lower_limit)
747
+ rng = self._get_random_state(rng)
748
+ out = self._cdf(x, mean, cov, maxpts, abseps, releps, lower_limit, rng)
734
749
  return out
735
750
 
736
751
  def rvs(self, mean=None, cov=1, size=1, random_state=None):
@@ -928,19 +943,20 @@ class multivariate_normal_frozen(multi_rv_frozen):
928
943
  def pdf(self, x):
929
944
  return np.exp(self.logpdf(x))
930
945
 
931
- def logcdf(self, x, *, lower_limit=None):
932
- cdf = self.cdf(x, lower_limit=lower_limit)
946
+ def logcdf(self, x, *, lower_limit=None, rng=None):
947
+ cdf = self.cdf(x, lower_limit=lower_limit, rng=rng)
933
948
  # the log of a negative real is complex, and cdf can be negative
934
949
  # if lower limit is greater than upper limit
935
950
  cdf = cdf + 0j if np.any(cdf < 0) else cdf
936
951
  out = np.log(cdf)
937
952
  return out
938
953
 
939
- def cdf(self, x, *, lower_limit=None):
954
+ def cdf(self, x, *, lower_limit=None, rng=None):
940
955
  x = self._dist._process_quantiles(x, self.dim)
956
+ rng = self._dist._get_random_state(rng)
941
957
  out = self._dist._cdf(x, self.mean, self.cov_object.covariance,
942
958
  self.maxpts, self.abseps, self.releps,
943
- lower_limit)
959
+ lower_limit, rng)
944
960
  return _squeeze_output(out)
945
961
 
946
962
  def rvs(self, size=1, random_state=None):
@@ -2014,8 +2030,8 @@ class wishart_gen(multi_rv_generic):
2014
2030
  raise ValueError("Array 'scale' must be square if it is two dimensional,"
2015
2031
  f" but scale.scale = {str(scale.shape)}.")
2016
2032
  elif scale.ndim > 2:
2017
- raise ValueError("Array 'scale' must be at most two-dimensional,"
2018
- " but scale.ndim = %d" % scale.ndim)
2033
+ raise ValueError(f"Array 'scale' must be at most two-dimensional, "
2034
+ f"but scale.ndim = {scale.ndim}")
2019
2035
 
2020
2036
  dim = scale.shape[0]
2021
2037
 
@@ -2055,9 +2071,9 @@ class wishart_gen(multi_rv_generic):
2055
2071
  "Quantiles must be square in the first two dimensions "
2056
2072
  f"if they are three dimensional, but x.shape = {str(x.shape)}.")
2057
2073
  elif x.ndim > 3:
2058
- raise ValueError("Quantiles must be at most two-dimensional with"
2059
- " an additional dimension for multiple"
2060
- "components, but x.ndim = %d" % x.ndim)
2074
+ raise ValueError(f"Quantiles must be at most two-dimensional with an "
2075
+ f"additional dimension for multiple components, "
2076
+ f"but x.ndim = {x.ndim}")
2061
2077
 
2062
2078
  # Now we have 3-dim array; should have shape [dim, dim, *]
2063
2079
  if not x.shape[0:2] == (dim, dim):
@@ -3260,17 +3276,27 @@ class multinomial_gen(multi_rv_generic):
3260
3276
  """
3261
3277
  return multinomial_frozen(n, p, seed)
3262
3278
 
3263
- def _process_parameters(self, n, p, eps=1e-15):
3279
+ def _process_parameters(self, n, p):
3264
3280
  """Returns: n_, p_, npcond.
3265
3281
 
3266
3282
  n_ and p_ are arrays of the correct shape; npcond is a boolean array
3267
3283
  flagging values out of the domain.
3268
3284
  """
3285
+ eps = np.finfo(np.result_type(np.asarray(p), np.float32)).eps * 10
3269
3286
  p = np.array(p, dtype=np.float64, copy=True)
3270
3287
  p_adjusted = 1. - p[..., :-1].sum(axis=-1)
3271
- i_adjusted = np.abs(p_adjusted) > eps
3288
+ # only make adjustment when it's significant
3289
+ i_adjusted = np.abs(1 - p.sum(axis=-1)) > eps
3272
3290
  p[i_adjusted, -1] = p_adjusted[i_adjusted]
3273
3291
 
3292
+ if np.any(i_adjusted):
3293
+ message = ("Some rows of `p` do not sum to 1.0 within tolerance of "
3294
+ f"{eps=}. Currently, the last element of these rows is adjusted "
3295
+ "to compensate, but this condition will produce NaNs "
3296
+ "beginning in SciPy 1.18.0. Please ensure that rows of `p` sum "
3297
+ "to 1.0 to avoid futher disruption.")
3298
+ warnings.warn(message, FutureWarning, stacklevel=3)
3299
+
3274
3300
  # true for bad p
3275
3301
  pcond = np.any(p < 0, axis=-1)
3276
3302
  pcond |= np.any(p > 1, axis=-1)
@@ -3294,9 +3320,9 @@ class multinomial_gen(multi_rv_generic):
3294
3320
  raise ValueError("x must be an array.")
3295
3321
 
3296
3322
  if xx.size != 0 and not xx.shape[-1] == p.shape[-1]:
3297
- raise ValueError("Size of each quantile should be size of p: "
3298
- "received %d, but expected %d." %
3299
- (xx.shape[-1], p.shape[-1]))
3323
+ raise ValueError(f"Size of each quantile should be size of p: "
3324
+ f"received {xx.shape[-1]}, but expected "
3325
+ f"{p.shape[-1]}.")
3300
3326
 
3301
3327
  # true for x out of the domain
3302
3328
  cond = np.any(xx != x, axis=-1)
@@ -3561,20 +3587,13 @@ class special_ortho_group_gen(multi_rv_generic):
3561
3587
 
3562
3588
  Notes
3563
3589
  -----
3564
- This class is wrapping the random_rot code from the MDP Toolkit,
3565
- https://github.com/mdp-toolkit/mdp-toolkit
3566
-
3567
- Return a random rotation matrix, drawn from the Haar distribution
3568
- (the only uniform distribution on SO(N)).
3569
- The algorithm is described in the paper
3570
- Stewart, G.W., "The efficient generation of random orthogonal
3571
- matrices with an application to condition estimators", SIAM Journal
3572
- on Numerical Analysis, 17(3), pp. 403-409, 1980.
3573
- For more information see
3574
- https://en.wikipedia.org/wiki/Orthogonal_matrix#Randomization
3590
+ The ``rvs`` method returns a random rotation matrix drawn from the Haar
3591
+ distribution, the only uniform distribution on SO(N). The algorithm generates
3592
+ a Haar-distributed orthogonal matrix in O(N) using the ``rvs`` method of
3593
+ `ortho_group`, then adjusts the matrix to ensure that the determinant is +1.
3575
3594
 
3576
- See also the similar `ortho_group`. For a random rotation in three
3577
- dimensions, see `scipy.spatial.transform.Rotation.random`.
3595
+ For a random rotation in three dimensions, see
3596
+ `scipy.spatial.transform.Rotation.random`.
3578
3597
 
3579
3598
  Examples
3580
3599
  --------
@@ -3620,9 +3639,9 @@ class special_ortho_group_gen(multi_rv_generic):
3620
3639
 
3621
3640
  def _process_parameters(self, dim):
3622
3641
  """Dimension N must be specified; it cannot be inferred."""
3623
- if dim is None or not np.isscalar(dim) or dim <= 1 or dim != int(dim):
3642
+ if dim is None or not np.isscalar(dim) or dim < 0 or dim != int(dim):
3624
3643
  raise ValueError("""Dimension of rotation must be specified,
3625
- and must be a scalar greater than 1.""")
3644
+ and must be a scalar nonnegative integer.""")
3626
3645
 
3627
3646
  return dim
3628
3647
 
@@ -3644,55 +3663,11 @@ class special_ortho_group_gen(multi_rv_generic):
3644
3663
  """
3645
3664
  random_state = self._get_random_state(random_state)
3646
3665
 
3647
- size = int(size)
3648
- size = (size,) if size > 1 else ()
3649
-
3650
- dim = self._process_parameters(dim)
3651
-
3652
- # H represents a (dim, dim) matrix, while D represents the diagonal of
3653
- # a (dim, dim) diagonal matrix. The algorithm that follows is
3654
- # broadcasted on the leading shape in `size` to vectorize along
3655
- # samples.
3656
- H = np.empty(size + (dim, dim))
3657
- H[..., :, :] = np.eye(dim)
3658
- D = np.empty(size + (dim,))
3659
-
3660
- for n in range(dim-1):
3661
-
3662
- # x is a vector with length dim-n, xrow and xcol are views of it as
3663
- # a row vector and column vector respectively. It's important they
3664
- # are views and not copies because we are going to modify x
3665
- # in-place.
3666
- x = random_state.normal(size=size + (dim-n,))
3667
- xrow = x[..., None, :]
3668
- xcol = x[..., :, None]
3669
-
3670
- # This is the squared norm of x, without vectorization it would be
3671
- # dot(x, x), to have proper broadcasting we use matmul and squeeze
3672
- # out (convert to scalar) the resulting 1x1 matrix
3673
- norm2 = np.matmul(xrow, xcol).squeeze((-2, -1))
3674
-
3675
- x0 = x[..., 0].copy()
3676
- D[..., n] = np.where(x0 != 0, np.sign(x0), 1)
3677
- x[..., 0] += D[..., n]*np.sqrt(norm2)
3678
-
3679
- # In renormalizing x we have to append an additional axis with
3680
- # [..., None] to broadcast the scalar against the vector x
3681
- x /= np.sqrt((norm2 - x0**2 + x[..., 0]**2) / 2.)[..., None]
3682
-
3683
- # Householder transformation, without vectorization the RHS can be
3684
- # written as outer(H @ x, x) (apart from the slicing)
3685
- H[..., :, n:] -= np.matmul(H[..., :, n:], xcol) * xrow
3686
-
3687
- D[..., -1] = (-1)**(dim-1)*D[..., :-1].prod(axis=-1)
3688
-
3689
- # Without vectorization this could be written as H = diag(D) @ H,
3690
- # left-multiplication by a diagonal matrix amounts to multiplying each
3691
- # row of H by an element of the diagonal, so we add a dummy axis for
3692
- # the column index
3693
- H *= D[..., :, None]
3694
- return H
3695
-
3666
+ q = ortho_group.rvs(dim, size, random_state)
3667
+ dets = np.linalg.det(q)
3668
+ if dim:
3669
+ q[..., 0, :] /= dets[..., np.newaxis]
3670
+ return q
3696
3671
 
3697
3672
  special_ortho_group = special_ortho_group_gen()
3698
3673
 
@@ -3807,9 +3782,9 @@ class ortho_group_gen(multi_rv_generic):
3807
3782
 
3808
3783
  def _process_parameters(self, dim):
3809
3784
  """Dimension N must be specified; it cannot be inferred."""
3810
- if dim is None or not np.isscalar(dim) or dim <= 1 or dim != int(dim):
3785
+ if dim is None or not np.isscalar(dim) or dim < 0 or dim != int(dim):
3811
3786
  raise ValueError("Dimension of rotation must be specified,"
3812
- "and must be a scalar greater than 1.")
3787
+ "and must be a scalar nonnegative integer.")
3813
3788
 
3814
3789
  return dim
3815
3790
 
@@ -3884,6 +3859,7 @@ class random_correlation_gen(multi_rv_generic):
3884
3859
  r"""A random correlation matrix.
3885
3860
 
3886
3861
  Return a random correlation matrix, given a vector of eigenvalues.
3862
+ The returned matrix is symmetric positive semidefinite with unit diagonal.
3887
3863
 
3888
3864
  The `eigs` keyword specifies the eigenvalues of the correlation matrix,
3889
3865
  and implies the dimension.
@@ -3896,7 +3872,8 @@ class random_correlation_gen(multi_rv_generic):
3896
3872
  Parameters
3897
3873
  ----------
3898
3874
  eigs : 1d ndarray
3899
- Eigenvalues of correlation matrix
3875
+ Eigenvalues of correlation matrix. All eigenvalues need to be non-negative and
3876
+ need to sum to the number of eigenvalues.
3900
3877
  seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
3901
3878
  If `seed` is None (or `np.random`), the `numpy.random.RandomState`
3902
3879
  singleton is used.
@@ -4162,7 +4139,7 @@ class unitary_group_gen(multi_rv_generic):
4162
4139
  Parameters
4163
4140
  ----------
4164
4141
  dim : scalar
4165
- Dimension of matrices, must be greater than 1.
4142
+ Dimension of matrices.
4166
4143
  seed : {None, int, np.random.RandomState, np.random.Generator}, optional
4167
4144
  Used for drawing random variates.
4168
4145
  If `seed` is `None`, the `~np.random.RandomState` singleton is used.
@@ -4219,9 +4196,9 @@ class unitary_group_gen(multi_rv_generic):
4219
4196
 
4220
4197
  def _process_parameters(self, dim):
4221
4198
  """Dimension N must be specified; it cannot be inferred."""
4222
- if dim is None or not np.isscalar(dim) or dim <= 1 or dim != int(dim):
4199
+ if dim is None or not np.isscalar(dim) or dim < 0 or dim != int(dim):
4223
4200
  raise ValueError("Dimension of rotation must be specified,"
4224
- "and must be a scalar greater than 1.")
4201
+ "and must be a scalar nonnegative integer.")
4225
4202
 
4226
4203
  return dim
4227
4204
 
@@ -4655,7 +4632,7 @@ class multivariate_t_gen(multi_rv_generic):
4655
4632
 
4656
4633
  # preserves ~12 digits accuracy up to at least `dim=1e5`. See gh-18465.
4657
4634
  threshold = dim * 100 * 4 / (np.log(dim) + 1)
4658
- return _lazywhere(df >= threshold, (dim, df), f=asymptotic, f2=regular)
4635
+ return xpx.apply_where(df >= threshold, (dim, df), asymptotic, regular)
4659
4636
 
4660
4637
  def entropy(self, loc=None, shape=1, df=1):
4661
4638
  """Calculate the differential entropy of a multivariate
@@ -4766,8 +4743,7 @@ class multivariate_t_gen(multi_rv_generic):
4766
4743
  shape = shape.reshape(1, 1)
4767
4744
 
4768
4745
  if loc.ndim != 1 or loc.shape[0] != dim:
4769
- raise ValueError("Array 'loc' must be a vector of length %d." %
4770
- dim)
4746
+ raise ValueError(f"Array 'loc' must be a vector of length {dim}.")
4771
4747
  if shape.ndim == 0:
4772
4748
  shape = shape * np.eye(dim)
4773
4749
  elif shape.ndim == 1:
@@ -4783,8 +4759,8 @@ class multivariate_t_gen(multi_rv_generic):
4783
4759
  msg = msg % (str(shape.shape), len(loc))
4784
4760
  raise ValueError(msg)
4785
4761
  elif shape.ndim > 2:
4786
- raise ValueError("Array 'cov' must be at most two-dimensional,"
4787
- " but cov.ndim = %d" % shape.ndim)
4762
+ raise ValueError(f"Array 'cov' must be at most two-dimensional, "
4763
+ f"but cov.ndim = {shape.ndim}")
4788
4764
 
4789
4765
  # Process degrees of freedom.
4790
4766
  if df is None:
@@ -5970,7 +5946,7 @@ alpha : array_like
5970
5946
  determines the dimensionality of the distribution. Each entry must be
5971
5947
  strictly positive.
5972
5948
  n : int or array_like
5973
- The number of trials. Each element must be a strictly positive integer.
5949
+ The number of trials. Each element must be a non-negative integer.
5974
5950
  """
5975
5951
 
5976
5952
  _dirichlet_mn_doc_frozen_callparams = ""
@@ -6012,8 +5988,8 @@ def _dirichlet_multinomial_check_parameters(alpha, n, x=None):
6012
5988
  raise ValueError("`alpha` must contain only positive values.")
6013
5989
 
6014
5990
  n_int = np.floor(n)
6015
- if np.any(n <= 0) or np.any(n != n_int):
6016
- raise ValueError("`n` must be a positive integer.")
5991
+ if np.any(n < 0) or np.any(n != n_int):
5992
+ raise ValueError("`n` must be a non-negative integer.")
6017
5993
  n = n_int
6018
5994
 
6019
5995
  sum_alpha = np.sum(alpha, axis=-1)
@@ -5,10 +5,10 @@ from numpy import inf
5
5
 
6
6
  from scipy import special
7
7
  from scipy.stats._distribution_infrastructure import (
8
- ContinuousDistribution, _RealDomain, _RealParameter, _Parameterization,
9
- _combine_docs)
8
+ ContinuousDistribution, DiscreteDistribution, _RealInterval, _IntegerInterval,
9
+ _RealParameter, _Parameterization, _combine_docs)
10
10
 
11
- __all__ = ['Normal', 'Uniform']
11
+ __all__ = ['Normal', 'Uniform', 'Binomial']
12
12
 
13
13
 
14
14
  class Normal(ContinuousDistribution):
@@ -25,9 +25,9 @@ class Normal(ContinuousDistribution):
25
25
  # `ShiftedScaledDistribution` allows this to be generated automatically from
26
26
  # an instance of `StandardNormal`, but the normal distribution is so frequently
27
27
  # used that it's worth a bit of code duplication to get better performance.
28
- _mu_domain = _RealDomain(endpoints=(-inf, inf))
29
- _sigma_domain = _RealDomain(endpoints=(0, inf))
30
- _x_support = _RealDomain(endpoints=(-inf, inf))
28
+ _mu_domain = _RealInterval(endpoints=(-inf, inf))
29
+ _sigma_domain = _RealInterval(endpoints=(0, inf))
30
+ _x_support = _RealInterval(endpoints=(-inf, inf))
31
31
 
32
32
  _mu_param = _RealParameter('mu', symbol=r'\mu', domain=_mu_domain,
33
33
  typical=(-1, 1))
@@ -114,7 +114,7 @@ class Normal(ContinuousDistribution):
114
114
  # exact is faster (and obviously more accurate) for reasonable orders
115
115
  return sigma**order * special.factorial2(int(order) - 1, exact=True)
116
116
 
117
- def _sample_formula(self, sample_shape, full_shape, rng, *, mu, sigma, **kwargs):
117
+ def _sample_formula(self, full_shape, rng, *, mu, sigma, **kwargs):
118
118
  return rng.normal(loc=mu, scale=sigma, size=full_shape)[()]
119
119
 
120
120
 
@@ -132,7 +132,7 @@ class StandardNormal(Normal):
132
132
  f(x) = \frac{1}{\sqrt{2 \pi}} \exp \left( -\frac{1}{2} x^2 \right)
133
133
 
134
134
  """
135
- _x_support = _RealDomain(endpoints=(-inf, inf))
135
+ _x_support = _RealInterval(endpoints=(-inf, inf))
136
136
  _x_param = _RealParameter('x', domain=_x_support, typical=(-5, 5))
137
137
  _variable = _x_param
138
138
  _parameterizations = []
@@ -196,7 +196,7 @@ class StandardNormal(Normal):
196
196
  def _moment_standardized_formula(self, order, **kwargs):
197
197
  return self._moment_raw_formula(order, **kwargs)
198
198
 
199
- def _sample_formula(self, sample_shape, full_shape, rng, **kwargs):
199
+ def _sample_formula(self, full_shape, rng, **kwargs):
200
200
  return rng.normal(size=full_shape)[()]
201
201
 
202
202
 
@@ -217,11 +217,11 @@ class _LogUniform(ContinuousDistribution):
217
217
 
218
218
  """
219
219
 
220
- _a_domain = _RealDomain(endpoints=(0, inf))
221
- _b_domain = _RealDomain(endpoints=('a', inf))
222
- _log_a_domain = _RealDomain(endpoints=(-inf, inf))
223
- _log_b_domain = _RealDomain(endpoints=('log_a', inf))
224
- _x_support = _RealDomain(endpoints=('a', 'b'), inclusive=(True, True))
220
+ _a_domain = _RealInterval(endpoints=(0, inf))
221
+ _b_domain = _RealInterval(endpoints=('a', inf))
222
+ _log_a_domain = _RealInterval(endpoints=(-inf, inf))
223
+ _log_b_domain = _RealInterval(endpoints=('log_a', inf))
224
+ _x_support = _RealInterval(endpoints=('a', 'b'), inclusive=(True, True))
225
225
 
226
226
  _a_param = _RealParameter('a', domain=_a_domain, typical=(1e-3, 0.9))
227
227
  _b_param = _RealParameter('b', domain=_b_domain, typical=(1.1, 1e3))
@@ -279,9 +279,9 @@ class Uniform(ContinuousDistribution):
279
279
 
280
280
  """
281
281
 
282
- _a_domain = _RealDomain(endpoints=(-inf, inf))
283
- _b_domain = _RealDomain(endpoints=('a', inf))
284
- _x_support = _RealDomain(endpoints=('a', 'b'), inclusive=(True, True))
282
+ _a_domain = _RealInterval(endpoints=(-inf, inf))
283
+ _b_domain = _RealInterval(endpoints=('a', inf))
284
+ _x_support = _RealInterval(endpoints=('a', 'b'), inclusive=(True, True))
285
285
 
286
286
  _a_param = _RealParameter('a', domain=_a_domain, typical=(1e-3, 0.9))
287
287
  _b_param = _RealParameter('b', domain=_b_domain, typical=(1.1, 1e3))
@@ -345,7 +345,7 @@ class Uniform(ContinuousDistribution):
345
345
 
346
346
  _moment_central_formula.orders = [2] # type: ignore[attr-defined]
347
347
 
348
- def _sample_formula(self, sample_shape, full_shape, rng, a, b, ab, **kwargs):
348
+ def _sample_formula(self, full_shape, rng, a, b, ab, **kwargs):
349
349
  try:
350
350
  return rng.uniform(a, b, size=full_shape)[()]
351
351
  except OverflowError: # happens when there are NaNs
@@ -354,8 +354,8 @@ class Uniform(ContinuousDistribution):
354
354
 
355
355
  class _Gamma(ContinuousDistribution):
356
356
  # Gamma distribution for testing only
357
- _a_domain = _RealDomain(endpoints=(0, inf))
358
- _x_support = _RealDomain(endpoints=(0, inf), inclusive=(False, False))
357
+ _a_domain = _RealInterval(endpoints=(0, inf))
358
+ _x_support = _RealInterval(endpoints=(0, inf), inclusive=(False, False))
359
359
 
360
360
  _a_param = _RealParameter('a', domain=_a_domain, typical=(0.1, 10))
361
361
  _x_param = _RealParameter('x', domain=_x_support, typical=(0.1, 10))
@@ -367,6 +367,83 @@ class _Gamma(ContinuousDistribution):
367
367
  return x ** (a - 1) * np.exp(-x) / special.gamma(a)
368
368
 
369
369
 
370
+ class Binomial(DiscreteDistribution):
371
+ r"""Binomial distribution with prescribed success probability and number of trials
372
+
373
+ The probability density function of the binomial distribution is:
374
+
375
+ .. math::
376
+
377
+ f(x) = {n \choose x} p^x (1 - p)^{n-x}
378
+
379
+ """
380
+ _n_domain = _IntegerInterval(endpoints=(0, inf), inclusive=(False, False))
381
+ _p_domain = _RealInterval(endpoints=(0, 1), inclusive=(False, False))
382
+ _x_support = _IntegerInterval(endpoints=(0, 'n'), inclusive=(True, True))
383
+
384
+ _n_param = _RealParameter('n', domain=_n_domain, typical=(10, 20))
385
+ _p_param = _RealParameter('p', domain=_p_domain, typical=(0.25, 0.75))
386
+ _x_param = _RealParameter('x', domain=_x_support, typical=(0, 10))
387
+
388
+ _parameterizations = [_Parameterization(_n_param, _p_param)]
389
+ _variable = _x_param
390
+
391
+ def __init__(self, *, n, p, **kwargs):
392
+ super().__init__(n=n, p=p, **kwargs)
393
+
394
+ def _pmf_formula(self, x, *, n, p, **kwargs):
395
+ return special._ufuncs._binom_pmf(x, n, p)
396
+
397
+ def _logpmf_formula(self, x, *, n, p, **kwargs):
398
+ # This implementation is from the ``scipy.stats.binom`` and could be improved
399
+ # by using a more numerically sound implementation of the absolute value of
400
+ # the binomial coefficient.
401
+ combiln = (
402
+ special.gammaln(n+1) - (special.gammaln(x+1) + special.gammaln(n-x+1))
403
+ )
404
+ return combiln + special.xlogy(x, p) + special.xlog1py(n-x, -p)
405
+
406
+ def _cdf_formula(self, x, *, n, p, **kwargs):
407
+ return special._ufuncs._binom_cdf(x, n, p)
408
+
409
+ def _ccdf_formula(self, x, *, n, p, **kwargs):
410
+ return special._ufuncs._binom_sf(x, n, p)
411
+
412
+ def _icdf_formula(self, x, *, n, p, **kwargs):
413
+ return special._ufuncs._binom_ppf(x, n, p)
414
+
415
+ def _iccdf_formula(self, x, *, n, p, **kwargs):
416
+ return special._ufuncs._binom_isf(x, n, p)
417
+
418
+ def _mode_formula(self, *, n, p, **kwargs):
419
+ # https://en.wikipedia.org/wiki/Binomial_distribution#Mode
420
+ mode = np.floor((n+1)*p)
421
+ mode = np.where(p == 1, mode - 1, mode)
422
+ return mode[()]
423
+
424
+ def _moment_raw_formula(self, order, *, n, p, **kwargs):
425
+ # https://en.wikipedia.org/wiki/Binomial_distribution#Higher_moments
426
+ if order == 1:
427
+ return n*p
428
+ if order == 2:
429
+ return n*p*(1 - p + n*p)
430
+ return None
431
+ _moment_raw_formula.orders = [1, 2] # type: ignore[attr-defined]
432
+
433
+ def _moment_central_formula(self, order, *, n, p, **kwargs):
434
+ # https://en.wikipedia.org/wiki/Binomial_distribution#Higher_moments
435
+ if order == 1:
436
+ return np.zeros_like(n)
437
+ if order == 2:
438
+ return n*p*(1 - p)
439
+ if order == 3:
440
+ return n*p*(1 - p)*(1 - 2*p)
441
+ if order == 4:
442
+ return n*p*(1 - p)*(1 + (3*n - 6)*p*(1 - p))
443
+ return None
444
+ _moment_central_formula.orders = [1, 2, 3, 4] # type: ignore[attr-defined]
445
+
446
+
370
447
  # Distribution classes need only define the summary and beginning of the extended
371
448
  # summary portion of the class documentation. All other documentation, including
372
449
  # examples, is generated automatically.