numpy 2.3.5__cp313-cp313-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.

Potentially problematic release.


This version of numpy might be problematic. Click here for more details.

Files changed (897) hide show
  1. numpy/__config__.py +170 -0
  2. numpy/__config__.pyi +102 -0
  3. numpy/__init__.cython-30.pxd +1241 -0
  4. numpy/__init__.pxd +1154 -0
  5. numpy/__init__.py +945 -0
  6. numpy/__init__.pyi +6147 -0
  7. numpy/_array_api_info.py +346 -0
  8. numpy/_array_api_info.pyi +207 -0
  9. numpy/_configtool.py +39 -0
  10. numpy/_configtool.pyi +1 -0
  11. numpy/_core/__init__.py +186 -0
  12. numpy/_core/__init__.pyi +2 -0
  13. numpy/_core/_add_newdocs.py +6967 -0
  14. numpy/_core/_add_newdocs.pyi +3 -0
  15. numpy/_core/_add_newdocs_scalars.py +390 -0
  16. numpy/_core/_add_newdocs_scalars.pyi +16 -0
  17. numpy/_core/_asarray.py +134 -0
  18. numpy/_core/_asarray.pyi +41 -0
  19. numpy/_core/_dtype.py +366 -0
  20. numpy/_core/_dtype.pyi +58 -0
  21. numpy/_core/_dtype_ctypes.py +120 -0
  22. numpy/_core/_dtype_ctypes.pyi +83 -0
  23. numpy/_core/_exceptions.py +162 -0
  24. numpy/_core/_exceptions.pyi +55 -0
  25. numpy/_core/_internal.py +958 -0
  26. numpy/_core/_internal.pyi +72 -0
  27. numpy/_core/_machar.py +355 -0
  28. numpy/_core/_machar.pyi +55 -0
  29. numpy/_core/_methods.py +255 -0
  30. numpy/_core/_methods.pyi +22 -0
  31. numpy/_core/_multiarray_tests.cpython-313-darwin.so +0 -0
  32. numpy/_core/_multiarray_umath.cpython-313-darwin.so +0 -0
  33. numpy/_core/_operand_flag_tests.cpython-313-darwin.so +0 -0
  34. numpy/_core/_rational_tests.cpython-313-darwin.so +0 -0
  35. numpy/_core/_simd.cpython-313-darwin.so +0 -0
  36. numpy/_core/_simd.pyi +25 -0
  37. numpy/_core/_string_helpers.py +100 -0
  38. numpy/_core/_string_helpers.pyi +12 -0
  39. numpy/_core/_struct_ufunc_tests.cpython-313-darwin.so +0 -0
  40. numpy/_core/_type_aliases.py +119 -0
  41. numpy/_core/_type_aliases.pyi +97 -0
  42. numpy/_core/_ufunc_config.py +491 -0
  43. numpy/_core/_ufunc_config.pyi +78 -0
  44. numpy/_core/_umath_tests.cpython-313-darwin.so +0 -0
  45. numpy/_core/arrayprint.py +1775 -0
  46. numpy/_core/arrayprint.pyi +238 -0
  47. numpy/_core/cversions.py +13 -0
  48. numpy/_core/defchararray.py +1427 -0
  49. numpy/_core/defchararray.pyi +1135 -0
  50. numpy/_core/einsumfunc.py +1498 -0
  51. numpy/_core/einsumfunc.pyi +184 -0
  52. numpy/_core/fromnumeric.py +4269 -0
  53. numpy/_core/fromnumeric.pyi +1750 -0
  54. numpy/_core/function_base.py +545 -0
  55. numpy/_core/function_base.pyi +278 -0
  56. numpy/_core/getlimits.py +748 -0
  57. numpy/_core/getlimits.pyi +3 -0
  58. numpy/_core/include/numpy/__multiarray_api.c +376 -0
  59. numpy/_core/include/numpy/__multiarray_api.h +1628 -0
  60. numpy/_core/include/numpy/__ufunc_api.c +54 -0
  61. numpy/_core/include/numpy/__ufunc_api.h +341 -0
  62. numpy/_core/include/numpy/_neighborhood_iterator_imp.h +90 -0
  63. numpy/_core/include/numpy/_numpyconfig.h +33 -0
  64. numpy/_core/include/numpy/_public_dtype_api_table.h +86 -0
  65. numpy/_core/include/numpy/arrayobject.h +7 -0
  66. numpy/_core/include/numpy/arrayscalars.h +196 -0
  67. numpy/_core/include/numpy/dtype_api.h +480 -0
  68. numpy/_core/include/numpy/halffloat.h +70 -0
  69. numpy/_core/include/numpy/ndarrayobject.h +304 -0
  70. numpy/_core/include/numpy/ndarraytypes.h +1950 -0
  71. numpy/_core/include/numpy/npy_2_compat.h +249 -0
  72. numpy/_core/include/numpy/npy_2_complexcompat.h +28 -0
  73. numpy/_core/include/numpy/npy_3kcompat.h +374 -0
  74. numpy/_core/include/numpy/npy_common.h +977 -0
  75. numpy/_core/include/numpy/npy_cpu.h +124 -0
  76. numpy/_core/include/numpy/npy_endian.h +78 -0
  77. numpy/_core/include/numpy/npy_math.h +602 -0
  78. numpy/_core/include/numpy/npy_no_deprecated_api.h +20 -0
  79. numpy/_core/include/numpy/npy_os.h +42 -0
  80. numpy/_core/include/numpy/numpyconfig.h +182 -0
  81. numpy/_core/include/numpy/random/LICENSE.txt +21 -0
  82. numpy/_core/include/numpy/random/bitgen.h +20 -0
  83. numpy/_core/include/numpy/random/distributions.h +209 -0
  84. numpy/_core/include/numpy/random/libdivide.h +2079 -0
  85. numpy/_core/include/numpy/ufuncobject.h +343 -0
  86. numpy/_core/include/numpy/utils.h +37 -0
  87. numpy/_core/lib/libnpymath.a +0 -0
  88. numpy/_core/lib/npy-pkg-config/mlib.ini +12 -0
  89. numpy/_core/lib/npy-pkg-config/npymath.ini +20 -0
  90. numpy/_core/lib/pkgconfig/numpy.pc +7 -0
  91. numpy/_core/memmap.py +363 -0
  92. numpy/_core/memmap.pyi +3 -0
  93. numpy/_core/multiarray.py +1762 -0
  94. numpy/_core/multiarray.pyi +1285 -0
  95. numpy/_core/numeric.py +2760 -0
  96. numpy/_core/numeric.pyi +882 -0
  97. numpy/_core/numerictypes.py +633 -0
  98. numpy/_core/numerictypes.pyi +197 -0
  99. numpy/_core/overrides.py +183 -0
  100. numpy/_core/overrides.pyi +48 -0
  101. numpy/_core/printoptions.py +32 -0
  102. numpy/_core/printoptions.pyi +28 -0
  103. numpy/_core/records.py +1089 -0
  104. numpy/_core/records.pyi +333 -0
  105. numpy/_core/shape_base.py +998 -0
  106. numpy/_core/shape_base.pyi +175 -0
  107. numpy/_core/strings.py +1829 -0
  108. numpy/_core/strings.pyi +511 -0
  109. numpy/_core/tests/_locales.py +72 -0
  110. numpy/_core/tests/_natype.py +205 -0
  111. numpy/_core/tests/data/astype_copy.pkl +0 -0
  112. numpy/_core/tests/data/generate_umath_validation_data.cpp +170 -0
  113. numpy/_core/tests/data/recarray_from_file.fits +0 -0
  114. numpy/_core/tests/data/umath-validation-set-README.txt +15 -0
  115. numpy/_core/tests/data/umath-validation-set-arccos.csv +1429 -0
  116. numpy/_core/tests/data/umath-validation-set-arccosh.csv +1429 -0
  117. numpy/_core/tests/data/umath-validation-set-arcsin.csv +1429 -0
  118. numpy/_core/tests/data/umath-validation-set-arcsinh.csv +1429 -0
  119. numpy/_core/tests/data/umath-validation-set-arctan.csv +1429 -0
  120. numpy/_core/tests/data/umath-validation-set-arctanh.csv +1429 -0
  121. numpy/_core/tests/data/umath-validation-set-cbrt.csv +1429 -0
  122. numpy/_core/tests/data/umath-validation-set-cos.csv +1375 -0
  123. numpy/_core/tests/data/umath-validation-set-cosh.csv +1429 -0
  124. numpy/_core/tests/data/umath-validation-set-exp.csv +412 -0
  125. numpy/_core/tests/data/umath-validation-set-exp2.csv +1429 -0
  126. numpy/_core/tests/data/umath-validation-set-expm1.csv +1429 -0
  127. numpy/_core/tests/data/umath-validation-set-log.csv +271 -0
  128. numpy/_core/tests/data/umath-validation-set-log10.csv +1629 -0
  129. numpy/_core/tests/data/umath-validation-set-log1p.csv +1429 -0
  130. numpy/_core/tests/data/umath-validation-set-log2.csv +1629 -0
  131. numpy/_core/tests/data/umath-validation-set-sin.csv +1370 -0
  132. numpy/_core/tests/data/umath-validation-set-sinh.csv +1429 -0
  133. numpy/_core/tests/data/umath-validation-set-tan.csv +1429 -0
  134. numpy/_core/tests/data/umath-validation-set-tanh.csv +1429 -0
  135. numpy/_core/tests/examples/cython/checks.pyx +373 -0
  136. numpy/_core/tests/examples/cython/meson.build +43 -0
  137. numpy/_core/tests/examples/cython/setup.py +39 -0
  138. numpy/_core/tests/examples/limited_api/limited_api1.c +17 -0
  139. numpy/_core/tests/examples/limited_api/limited_api2.pyx +11 -0
  140. numpy/_core/tests/examples/limited_api/limited_api_latest.c +19 -0
  141. numpy/_core/tests/examples/limited_api/meson.build +59 -0
  142. numpy/_core/tests/examples/limited_api/setup.py +24 -0
  143. numpy/_core/tests/test__exceptions.py +90 -0
  144. numpy/_core/tests/test_abc.py +54 -0
  145. numpy/_core/tests/test_api.py +654 -0
  146. numpy/_core/tests/test_argparse.py +92 -0
  147. numpy/_core/tests/test_array_api_info.py +113 -0
  148. numpy/_core/tests/test_array_coercion.py +911 -0
  149. numpy/_core/tests/test_array_interface.py +222 -0
  150. numpy/_core/tests/test_arraymethod.py +84 -0
  151. numpy/_core/tests/test_arrayobject.py +75 -0
  152. numpy/_core/tests/test_arrayprint.py +1328 -0
  153. numpy/_core/tests/test_casting_floatingpoint_errors.py +154 -0
  154. numpy/_core/tests/test_casting_unittests.py +817 -0
  155. numpy/_core/tests/test_conversion_utils.py +206 -0
  156. numpy/_core/tests/test_cpu_dispatcher.py +49 -0
  157. numpy/_core/tests/test_cpu_features.py +432 -0
  158. numpy/_core/tests/test_custom_dtypes.py +315 -0
  159. numpy/_core/tests/test_cython.py +351 -0
  160. numpy/_core/tests/test_datetime.py +2734 -0
  161. numpy/_core/tests/test_defchararray.py +825 -0
  162. numpy/_core/tests/test_deprecations.py +454 -0
  163. numpy/_core/tests/test_dlpack.py +190 -0
  164. numpy/_core/tests/test_dtype.py +1995 -0
  165. numpy/_core/tests/test_einsum.py +1317 -0
  166. numpy/_core/tests/test_errstate.py +131 -0
  167. numpy/_core/tests/test_extint128.py +217 -0
  168. numpy/_core/tests/test_function_base.py +503 -0
  169. numpy/_core/tests/test_getlimits.py +205 -0
  170. numpy/_core/tests/test_half.py +568 -0
  171. numpy/_core/tests/test_hashtable.py +35 -0
  172. numpy/_core/tests/test_indexerrors.py +125 -0
  173. numpy/_core/tests/test_indexing.py +1455 -0
  174. numpy/_core/tests/test_item_selection.py +167 -0
  175. numpy/_core/tests/test_limited_api.py +102 -0
  176. numpy/_core/tests/test_longdouble.py +369 -0
  177. numpy/_core/tests/test_machar.py +30 -0
  178. numpy/_core/tests/test_mem_overlap.py +930 -0
  179. numpy/_core/tests/test_mem_policy.py +452 -0
  180. numpy/_core/tests/test_memmap.py +246 -0
  181. numpy/_core/tests/test_multiarray.py +10577 -0
  182. numpy/_core/tests/test_multithreading.py +292 -0
  183. numpy/_core/tests/test_nditer.py +3498 -0
  184. numpy/_core/tests/test_nep50_promotions.py +287 -0
  185. numpy/_core/tests/test_numeric.py +4247 -0
  186. numpy/_core/tests/test_numerictypes.py +651 -0
  187. numpy/_core/tests/test_overrides.py +791 -0
  188. numpy/_core/tests/test_print.py +200 -0
  189. numpy/_core/tests/test_protocols.py +46 -0
  190. numpy/_core/tests/test_records.py +544 -0
  191. numpy/_core/tests/test_regression.py +2670 -0
  192. numpy/_core/tests/test_scalar_ctors.py +207 -0
  193. numpy/_core/tests/test_scalar_methods.py +246 -0
  194. numpy/_core/tests/test_scalarbuffer.py +153 -0
  195. numpy/_core/tests/test_scalarinherit.py +105 -0
  196. numpy/_core/tests/test_scalarmath.py +1176 -0
  197. numpy/_core/tests/test_scalarprint.py +403 -0
  198. numpy/_core/tests/test_shape_base.py +891 -0
  199. numpy/_core/tests/test_simd.py +1341 -0
  200. numpy/_core/tests/test_simd_module.py +103 -0
  201. numpy/_core/tests/test_stringdtype.py +1814 -0
  202. numpy/_core/tests/test_strings.py +1499 -0
  203. numpy/_core/tests/test_ufunc.py +3313 -0
  204. numpy/_core/tests/test_umath.py +4928 -0
  205. numpy/_core/tests/test_umath_accuracy.py +124 -0
  206. numpy/_core/tests/test_umath_complex.py +626 -0
  207. numpy/_core/tests/test_unicode.py +368 -0
  208. numpy/_core/umath.py +60 -0
  209. numpy/_core/umath.pyi +197 -0
  210. numpy/_distributor_init.py +15 -0
  211. numpy/_distributor_init.pyi +1 -0
  212. numpy/_expired_attrs_2_0.py +79 -0
  213. numpy/_expired_attrs_2_0.pyi +62 -0
  214. numpy/_globals.py +96 -0
  215. numpy/_globals.pyi +17 -0
  216. numpy/_pyinstaller/__init__.py +0 -0
  217. numpy/_pyinstaller/__init__.pyi +0 -0
  218. numpy/_pyinstaller/hook-numpy.py +36 -0
  219. numpy/_pyinstaller/hook-numpy.pyi +13 -0
  220. numpy/_pyinstaller/tests/__init__.py +16 -0
  221. numpy/_pyinstaller/tests/pyinstaller-smoke.py +32 -0
  222. numpy/_pyinstaller/tests/test_pyinstaller.py +35 -0
  223. numpy/_pytesttester.py +201 -0
  224. numpy/_pytesttester.pyi +18 -0
  225. numpy/_typing/__init__.py +148 -0
  226. numpy/_typing/_add_docstring.py +153 -0
  227. numpy/_typing/_array_like.py +106 -0
  228. numpy/_typing/_char_codes.py +213 -0
  229. numpy/_typing/_dtype_like.py +114 -0
  230. numpy/_typing/_extended_precision.py +15 -0
  231. numpy/_typing/_nbit.py +19 -0
  232. numpy/_typing/_nbit_base.py +94 -0
  233. numpy/_typing/_nbit_base.pyi +40 -0
  234. numpy/_typing/_nested_sequence.py +79 -0
  235. numpy/_typing/_scalars.py +20 -0
  236. numpy/_typing/_shape.py +8 -0
  237. numpy/_typing/_ufunc.py +7 -0
  238. numpy/_typing/_ufunc.pyi +941 -0
  239. numpy/_utils/__init__.py +95 -0
  240. numpy/_utils/__init__.pyi +30 -0
  241. numpy/_utils/_convertions.py +18 -0
  242. numpy/_utils/_convertions.pyi +4 -0
  243. numpy/_utils/_inspect.py +192 -0
  244. numpy/_utils/_inspect.pyi +71 -0
  245. numpy/_utils/_pep440.py +486 -0
  246. numpy/_utils/_pep440.pyi +121 -0
  247. numpy/char/__init__.py +2 -0
  248. numpy/char/__init__.pyi +111 -0
  249. numpy/conftest.py +258 -0
  250. numpy/core/__init__.py +33 -0
  251. numpy/core/__init__.pyi +0 -0
  252. numpy/core/_dtype.py +10 -0
  253. numpy/core/_dtype.pyi +0 -0
  254. numpy/core/_dtype_ctypes.py +10 -0
  255. numpy/core/_dtype_ctypes.pyi +0 -0
  256. numpy/core/_internal.py +27 -0
  257. numpy/core/_multiarray_umath.py +57 -0
  258. numpy/core/_utils.py +21 -0
  259. numpy/core/arrayprint.py +10 -0
  260. numpy/core/defchararray.py +10 -0
  261. numpy/core/einsumfunc.py +10 -0
  262. numpy/core/fromnumeric.py +10 -0
  263. numpy/core/function_base.py +10 -0
  264. numpy/core/getlimits.py +10 -0
  265. numpy/core/multiarray.py +25 -0
  266. numpy/core/numeric.py +12 -0
  267. numpy/core/numerictypes.py +10 -0
  268. numpy/core/overrides.py +10 -0
  269. numpy/core/overrides.pyi +7 -0
  270. numpy/core/records.py +10 -0
  271. numpy/core/shape_base.py +10 -0
  272. numpy/core/umath.py +10 -0
  273. numpy/ctypeslib/__init__.py +13 -0
  274. numpy/ctypeslib/__init__.pyi +33 -0
  275. numpy/ctypeslib/_ctypeslib.py +603 -0
  276. numpy/ctypeslib/_ctypeslib.pyi +245 -0
  277. numpy/doc/ufuncs.py +138 -0
  278. numpy/dtypes.py +41 -0
  279. numpy/dtypes.pyi +631 -0
  280. numpy/exceptions.py +247 -0
  281. numpy/exceptions.pyi +27 -0
  282. numpy/f2py/__init__.py +86 -0
  283. numpy/f2py/__init__.pyi +6 -0
  284. numpy/f2py/__main__.py +5 -0
  285. numpy/f2py/__version__.py +1 -0
  286. numpy/f2py/__version__.pyi +1 -0
  287. numpy/f2py/_backends/__init__.py +9 -0
  288. numpy/f2py/_backends/__init__.pyi +5 -0
  289. numpy/f2py/_backends/_backend.py +44 -0
  290. numpy/f2py/_backends/_backend.pyi +46 -0
  291. numpy/f2py/_backends/_distutils.py +76 -0
  292. numpy/f2py/_backends/_distutils.pyi +13 -0
  293. numpy/f2py/_backends/_meson.py +231 -0
  294. numpy/f2py/_backends/_meson.pyi +63 -0
  295. numpy/f2py/_backends/meson.build.template +55 -0
  296. numpy/f2py/_isocbind.py +62 -0
  297. numpy/f2py/_isocbind.pyi +13 -0
  298. numpy/f2py/_src_pyf.py +247 -0
  299. numpy/f2py/_src_pyf.pyi +29 -0
  300. numpy/f2py/auxfuncs.py +1004 -0
  301. numpy/f2py/auxfuncs.pyi +264 -0
  302. numpy/f2py/capi_maps.py +811 -0
  303. numpy/f2py/capi_maps.pyi +33 -0
  304. numpy/f2py/cb_rules.py +665 -0
  305. numpy/f2py/cb_rules.pyi +17 -0
  306. numpy/f2py/cfuncs.py +1563 -0
  307. numpy/f2py/cfuncs.pyi +31 -0
  308. numpy/f2py/common_rules.py +143 -0
  309. numpy/f2py/common_rules.pyi +9 -0
  310. numpy/f2py/crackfortran.py +3725 -0
  311. numpy/f2py/crackfortran.pyi +258 -0
  312. numpy/f2py/diagnose.py +149 -0
  313. numpy/f2py/diagnose.pyi +1 -0
  314. numpy/f2py/f2py2e.py +786 -0
  315. numpy/f2py/f2py2e.pyi +76 -0
  316. numpy/f2py/f90mod_rules.py +269 -0
  317. numpy/f2py/f90mod_rules.pyi +16 -0
  318. numpy/f2py/func2subr.py +329 -0
  319. numpy/f2py/func2subr.pyi +7 -0
  320. numpy/f2py/rules.py +1629 -0
  321. numpy/f2py/rules.pyi +43 -0
  322. numpy/f2py/setup.cfg +3 -0
  323. numpy/f2py/src/fortranobject.c +1436 -0
  324. numpy/f2py/src/fortranobject.h +173 -0
  325. numpy/f2py/symbolic.py +1516 -0
  326. numpy/f2py/symbolic.pyi +221 -0
  327. numpy/f2py/tests/__init__.py +16 -0
  328. numpy/f2py/tests/src/abstract_interface/foo.f90 +34 -0
  329. numpy/f2py/tests/src/abstract_interface/gh18403_mod.f90 +6 -0
  330. numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c +235 -0
  331. numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap +1 -0
  332. numpy/f2py/tests/src/assumed_shape/foo_free.f90 +34 -0
  333. numpy/f2py/tests/src/assumed_shape/foo_mod.f90 +41 -0
  334. numpy/f2py/tests/src/assumed_shape/foo_use.f90 +19 -0
  335. numpy/f2py/tests/src/assumed_shape/precision.f90 +4 -0
  336. numpy/f2py/tests/src/block_docstring/foo.f +6 -0
  337. numpy/f2py/tests/src/callback/foo.f +62 -0
  338. numpy/f2py/tests/src/callback/gh17797.f90 +7 -0
  339. numpy/f2py/tests/src/callback/gh18335.f90 +17 -0
  340. numpy/f2py/tests/src/callback/gh25211.f +10 -0
  341. numpy/f2py/tests/src/callback/gh25211.pyf +18 -0
  342. numpy/f2py/tests/src/callback/gh26681.f90 +18 -0
  343. numpy/f2py/tests/src/cli/gh_22819.pyf +6 -0
  344. numpy/f2py/tests/src/cli/hi77.f +3 -0
  345. numpy/f2py/tests/src/cli/hiworld.f90 +3 -0
  346. numpy/f2py/tests/src/common/block.f +11 -0
  347. numpy/f2py/tests/src/common/gh19161.f90 +10 -0
  348. numpy/f2py/tests/src/crackfortran/accesstype.f90 +13 -0
  349. numpy/f2py/tests/src/crackfortran/common_with_division.f +17 -0
  350. numpy/f2py/tests/src/crackfortran/data_common.f +8 -0
  351. numpy/f2py/tests/src/crackfortran/data_multiplier.f +5 -0
  352. numpy/f2py/tests/src/crackfortran/data_stmts.f90 +20 -0
  353. numpy/f2py/tests/src/crackfortran/data_with_comments.f +8 -0
  354. numpy/f2py/tests/src/crackfortran/foo_deps.f90 +6 -0
  355. numpy/f2py/tests/src/crackfortran/gh15035.f +16 -0
  356. numpy/f2py/tests/src/crackfortran/gh17859.f +12 -0
  357. numpy/f2py/tests/src/crackfortran/gh22648.pyf +7 -0
  358. numpy/f2py/tests/src/crackfortran/gh23533.f +5 -0
  359. numpy/f2py/tests/src/crackfortran/gh23598.f90 +4 -0
  360. numpy/f2py/tests/src/crackfortran/gh23598Warn.f90 +11 -0
  361. numpy/f2py/tests/src/crackfortran/gh23879.f90 +20 -0
  362. numpy/f2py/tests/src/crackfortran/gh27697.f90 +12 -0
  363. numpy/f2py/tests/src/crackfortran/gh2848.f90 +13 -0
  364. numpy/f2py/tests/src/crackfortran/operators.f90 +49 -0
  365. numpy/f2py/tests/src/crackfortran/privatemod.f90 +11 -0
  366. numpy/f2py/tests/src/crackfortran/publicmod.f90 +10 -0
  367. numpy/f2py/tests/src/crackfortran/pubprivmod.f90 +10 -0
  368. numpy/f2py/tests/src/crackfortran/unicode_comment.f90 +4 -0
  369. numpy/f2py/tests/src/f2cmap/.f2py_f2cmap +1 -0
  370. numpy/f2py/tests/src/f2cmap/isoFortranEnvMap.f90 +9 -0
  371. numpy/f2py/tests/src/isocintrin/isoCtests.f90 +34 -0
  372. numpy/f2py/tests/src/kind/foo.f90 +20 -0
  373. numpy/f2py/tests/src/mixed/foo.f +5 -0
  374. numpy/f2py/tests/src/mixed/foo_fixed.f90 +8 -0
  375. numpy/f2py/tests/src/mixed/foo_free.f90 +8 -0
  376. numpy/f2py/tests/src/modules/gh25337/data.f90 +8 -0
  377. numpy/f2py/tests/src/modules/gh25337/use_data.f90 +6 -0
  378. numpy/f2py/tests/src/modules/gh26920/two_mods_with_no_public_entities.f90 +21 -0
  379. numpy/f2py/tests/src/modules/gh26920/two_mods_with_one_public_routine.f90 +21 -0
  380. numpy/f2py/tests/src/modules/module_data_docstring.f90 +12 -0
  381. numpy/f2py/tests/src/modules/use_modules.f90 +20 -0
  382. numpy/f2py/tests/src/negative_bounds/issue_20853.f90 +7 -0
  383. numpy/f2py/tests/src/parameter/constant_array.f90 +45 -0
  384. numpy/f2py/tests/src/parameter/constant_both.f90 +57 -0
  385. numpy/f2py/tests/src/parameter/constant_compound.f90 +15 -0
  386. numpy/f2py/tests/src/parameter/constant_integer.f90 +22 -0
  387. numpy/f2py/tests/src/parameter/constant_non_compound.f90 +23 -0
  388. numpy/f2py/tests/src/parameter/constant_real.f90 +23 -0
  389. numpy/f2py/tests/src/quoted_character/foo.f +14 -0
  390. numpy/f2py/tests/src/regression/AB.inc +1 -0
  391. numpy/f2py/tests/src/regression/assignOnlyModule.f90 +25 -0
  392. numpy/f2py/tests/src/regression/datonly.f90 +17 -0
  393. numpy/f2py/tests/src/regression/f77comments.f +26 -0
  394. numpy/f2py/tests/src/regression/f77fixedform.f95 +5 -0
  395. numpy/f2py/tests/src/regression/f90continuation.f90 +9 -0
  396. numpy/f2py/tests/src/regression/incfile.f90 +5 -0
  397. numpy/f2py/tests/src/regression/inout.f90 +9 -0
  398. numpy/f2py/tests/src/regression/lower_f2py_fortran.f90 +5 -0
  399. numpy/f2py/tests/src/regression/mod_derived_types.f90 +23 -0
  400. numpy/f2py/tests/src/return_character/foo77.f +45 -0
  401. numpy/f2py/tests/src/return_character/foo90.f90 +48 -0
  402. numpy/f2py/tests/src/return_complex/foo77.f +45 -0
  403. numpy/f2py/tests/src/return_complex/foo90.f90 +48 -0
  404. numpy/f2py/tests/src/return_integer/foo77.f +56 -0
  405. numpy/f2py/tests/src/return_integer/foo90.f90 +59 -0
  406. numpy/f2py/tests/src/return_logical/foo77.f +56 -0
  407. numpy/f2py/tests/src/return_logical/foo90.f90 +59 -0
  408. numpy/f2py/tests/src/return_real/foo77.f +45 -0
  409. numpy/f2py/tests/src/return_real/foo90.f90 +48 -0
  410. numpy/f2py/tests/src/routines/funcfortranname.f +5 -0
  411. numpy/f2py/tests/src/routines/funcfortranname.pyf +11 -0
  412. numpy/f2py/tests/src/routines/subrout.f +4 -0
  413. numpy/f2py/tests/src/routines/subrout.pyf +10 -0
  414. numpy/f2py/tests/src/size/foo.f90 +44 -0
  415. numpy/f2py/tests/src/string/char.f90 +29 -0
  416. numpy/f2py/tests/src/string/fixed_string.f90 +34 -0
  417. numpy/f2py/tests/src/string/gh24008.f +8 -0
  418. numpy/f2py/tests/src/string/gh24662.f90 +7 -0
  419. numpy/f2py/tests/src/string/gh25286.f90 +14 -0
  420. numpy/f2py/tests/src/string/gh25286.pyf +12 -0
  421. numpy/f2py/tests/src/string/gh25286_bc.pyf +12 -0
  422. numpy/f2py/tests/src/string/scalar_string.f90 +9 -0
  423. numpy/f2py/tests/src/string/string.f +12 -0
  424. numpy/f2py/tests/src/value_attrspec/gh21665.f90 +9 -0
  425. numpy/f2py/tests/test_abstract_interface.py +26 -0
  426. numpy/f2py/tests/test_array_from_pyobj.py +678 -0
  427. numpy/f2py/tests/test_assumed_shape.py +50 -0
  428. numpy/f2py/tests/test_block_docstring.py +20 -0
  429. numpy/f2py/tests/test_callback.py +263 -0
  430. numpy/f2py/tests/test_character.py +641 -0
  431. numpy/f2py/tests/test_common.py +23 -0
  432. numpy/f2py/tests/test_crackfortran.py +421 -0
  433. numpy/f2py/tests/test_data.py +71 -0
  434. numpy/f2py/tests/test_docs.py +64 -0
  435. numpy/f2py/tests/test_f2cmap.py +17 -0
  436. numpy/f2py/tests/test_f2py2e.py +964 -0
  437. numpy/f2py/tests/test_isoc.py +56 -0
  438. numpy/f2py/tests/test_kind.py +53 -0
  439. numpy/f2py/tests/test_mixed.py +35 -0
  440. numpy/f2py/tests/test_modules.py +83 -0
  441. numpy/f2py/tests/test_parameter.py +129 -0
  442. numpy/f2py/tests/test_pyf_src.py +43 -0
  443. numpy/f2py/tests/test_quoted_character.py +18 -0
  444. numpy/f2py/tests/test_regression.py +187 -0
  445. numpy/f2py/tests/test_return_character.py +48 -0
  446. numpy/f2py/tests/test_return_complex.py +67 -0
  447. numpy/f2py/tests/test_return_integer.py +55 -0
  448. numpy/f2py/tests/test_return_logical.py +65 -0
  449. numpy/f2py/tests/test_return_real.py +109 -0
  450. numpy/f2py/tests/test_routines.py +29 -0
  451. numpy/f2py/tests/test_semicolon_split.py +75 -0
  452. numpy/f2py/tests/test_size.py +45 -0
  453. numpy/f2py/tests/test_string.py +100 -0
  454. numpy/f2py/tests/test_symbolic.py +495 -0
  455. numpy/f2py/tests/test_value_attrspec.py +15 -0
  456. numpy/f2py/tests/util.py +442 -0
  457. numpy/f2py/use_rules.py +99 -0
  458. numpy/f2py/use_rules.pyi +9 -0
  459. numpy/fft/__init__.py +215 -0
  460. numpy/fft/__init__.pyi +43 -0
  461. numpy/fft/_helper.py +235 -0
  462. numpy/fft/_helper.pyi +45 -0
  463. numpy/fft/_pocketfft.py +1693 -0
  464. numpy/fft/_pocketfft.pyi +138 -0
  465. numpy/fft/_pocketfft_umath.cpython-313-darwin.so +0 -0
  466. numpy/fft/helper.py +17 -0
  467. numpy/fft/helper.pyi +22 -0
  468. numpy/fft/tests/__init__.py +0 -0
  469. numpy/fft/tests/test_helper.py +167 -0
  470. numpy/fft/tests/test_pocketfft.py +589 -0
  471. numpy/lib/__init__.py +97 -0
  472. numpy/lib/__init__.pyi +44 -0
  473. numpy/lib/_array_utils_impl.py +62 -0
  474. numpy/lib/_array_utils_impl.pyi +26 -0
  475. numpy/lib/_arraypad_impl.py +890 -0
  476. numpy/lib/_arraypad_impl.pyi +89 -0
  477. numpy/lib/_arraysetops_impl.py +1260 -0
  478. numpy/lib/_arraysetops_impl.pyi +468 -0
  479. numpy/lib/_arrayterator_impl.py +224 -0
  480. numpy/lib/_arrayterator_impl.pyi +46 -0
  481. numpy/lib/_datasource.py +700 -0
  482. numpy/lib/_datasource.pyi +31 -0
  483. numpy/lib/_format_impl.py +1036 -0
  484. numpy/lib/_format_impl.pyi +26 -0
  485. numpy/lib/_function_base_impl.py +5844 -0
  486. numpy/lib/_function_base_impl.pyi +1164 -0
  487. numpy/lib/_histograms_impl.py +1085 -0
  488. numpy/lib/_histograms_impl.pyi +50 -0
  489. numpy/lib/_index_tricks_impl.py +1067 -0
  490. numpy/lib/_index_tricks_impl.pyi +208 -0
  491. numpy/lib/_iotools.py +900 -0
  492. numpy/lib/_iotools.pyi +114 -0
  493. numpy/lib/_nanfunctions_impl.py +2024 -0
  494. numpy/lib/_nanfunctions_impl.pyi +52 -0
  495. numpy/lib/_npyio_impl.py +2596 -0
  496. numpy/lib/_npyio_impl.pyi +301 -0
  497. numpy/lib/_polynomial_impl.py +1465 -0
  498. numpy/lib/_polynomial_impl.pyi +318 -0
  499. numpy/lib/_scimath_impl.py +642 -0
  500. numpy/lib/_scimath_impl.pyi +93 -0
  501. numpy/lib/_shape_base_impl.py +1301 -0
  502. numpy/lib/_shape_base_impl.pyi +235 -0
  503. numpy/lib/_stride_tricks_impl.py +549 -0
  504. numpy/lib/_stride_tricks_impl.pyi +74 -0
  505. numpy/lib/_twodim_base_impl.py +1201 -0
  506. numpy/lib/_twodim_base_impl.pyi +438 -0
  507. numpy/lib/_type_check_impl.py +699 -0
  508. numpy/lib/_type_check_impl.pyi +350 -0
  509. numpy/lib/_ufunclike_impl.py +207 -0
  510. numpy/lib/_ufunclike_impl.pyi +67 -0
  511. numpy/lib/_user_array_impl.py +299 -0
  512. numpy/lib/_user_array_impl.pyi +225 -0
  513. numpy/lib/_utils_impl.py +784 -0
  514. numpy/lib/_utils_impl.pyi +10 -0
  515. numpy/lib/_version.py +154 -0
  516. numpy/lib/_version.pyi +17 -0
  517. numpy/lib/array_utils.py +7 -0
  518. numpy/lib/array_utils.pyi +12 -0
  519. numpy/lib/format.py +24 -0
  520. numpy/lib/format.pyi +66 -0
  521. numpy/lib/introspect.py +95 -0
  522. numpy/lib/introspect.pyi +3 -0
  523. numpy/lib/mixins.py +180 -0
  524. numpy/lib/mixins.pyi +77 -0
  525. numpy/lib/npyio.py +1 -0
  526. numpy/lib/npyio.pyi +9 -0
  527. numpy/lib/recfunctions.py +1681 -0
  528. numpy/lib/recfunctions.pyi +435 -0
  529. numpy/lib/scimath.py +13 -0
  530. numpy/lib/scimath.pyi +30 -0
  531. numpy/lib/stride_tricks.py +1 -0
  532. numpy/lib/stride_tricks.pyi +6 -0
  533. numpy/lib/tests/__init__.py +0 -0
  534. numpy/lib/tests/data/py2-np0-objarr.npy +0 -0
  535. numpy/lib/tests/data/py2-objarr.npy +0 -0
  536. numpy/lib/tests/data/py2-objarr.npz +0 -0
  537. numpy/lib/tests/data/py3-objarr.npy +0 -0
  538. numpy/lib/tests/data/py3-objarr.npz +0 -0
  539. numpy/lib/tests/data/python3.npy +0 -0
  540. numpy/lib/tests/data/win64python2.npy +0 -0
  541. numpy/lib/tests/test__datasource.py +352 -0
  542. numpy/lib/tests/test__iotools.py +360 -0
  543. numpy/lib/tests/test__version.py +64 -0
  544. numpy/lib/tests/test_array_utils.py +32 -0
  545. numpy/lib/tests/test_arraypad.py +1415 -0
  546. numpy/lib/tests/test_arraysetops.py +1074 -0
  547. numpy/lib/tests/test_arrayterator.py +46 -0
  548. numpy/lib/tests/test_format.py +1054 -0
  549. numpy/lib/tests/test_function_base.py +4573 -0
  550. numpy/lib/tests/test_histograms.py +855 -0
  551. numpy/lib/tests/test_index_tricks.py +573 -0
  552. numpy/lib/tests/test_io.py +2848 -0
  553. numpy/lib/tests/test_loadtxt.py +1101 -0
  554. numpy/lib/tests/test_mixins.py +215 -0
  555. numpy/lib/tests/test_nanfunctions.py +1438 -0
  556. numpy/lib/tests/test_packbits.py +376 -0
  557. numpy/lib/tests/test_polynomial.py +320 -0
  558. numpy/lib/tests/test_recfunctions.py +1052 -0
  559. numpy/lib/tests/test_regression.py +231 -0
  560. numpy/lib/tests/test_shape_base.py +813 -0
  561. numpy/lib/tests/test_stride_tricks.py +656 -0
  562. numpy/lib/tests/test_twodim_base.py +559 -0
  563. numpy/lib/tests/test_type_check.py +473 -0
  564. numpy/lib/tests/test_ufunclike.py +97 -0
  565. numpy/lib/tests/test_utils.py +80 -0
  566. numpy/lib/user_array.py +1 -0
  567. numpy/lib/user_array.pyi +1 -0
  568. numpy/linalg/__init__.py +98 -0
  569. numpy/linalg/__init__.pyi +73 -0
  570. numpy/linalg/_linalg.py +3682 -0
  571. numpy/linalg/_linalg.pyi +475 -0
  572. numpy/linalg/_umath_linalg.cpython-313-darwin.so +0 -0
  573. numpy/linalg/_umath_linalg.pyi +61 -0
  574. numpy/linalg/lapack_lite.cpython-313-darwin.so +0 -0
  575. numpy/linalg/lapack_lite.pyi +141 -0
  576. numpy/linalg/linalg.py +17 -0
  577. numpy/linalg/linalg.pyi +69 -0
  578. numpy/linalg/tests/__init__.py +0 -0
  579. numpy/linalg/tests/test_deprecations.py +20 -0
  580. numpy/linalg/tests/test_linalg.py +2443 -0
  581. numpy/linalg/tests/test_regression.py +181 -0
  582. numpy/ma/API_CHANGES.txt +135 -0
  583. numpy/ma/LICENSE +24 -0
  584. numpy/ma/README.rst +236 -0
  585. numpy/ma/__init__.py +53 -0
  586. numpy/ma/__init__.pyi +458 -0
  587. numpy/ma/core.py +8933 -0
  588. numpy/ma/core.pyi +1462 -0
  589. numpy/ma/extras.py +2344 -0
  590. numpy/ma/extras.pyi +138 -0
  591. numpy/ma/mrecords.py +773 -0
  592. numpy/ma/mrecords.pyi +96 -0
  593. numpy/ma/tests/__init__.py +0 -0
  594. numpy/ma/tests/test_arrayobject.py +40 -0
  595. numpy/ma/tests/test_core.py +5886 -0
  596. numpy/ma/tests/test_deprecations.py +87 -0
  597. numpy/ma/tests/test_extras.py +1998 -0
  598. numpy/ma/tests/test_mrecords.py +497 -0
  599. numpy/ma/tests/test_old_ma.py +942 -0
  600. numpy/ma/tests/test_regression.py +100 -0
  601. numpy/ma/tests/test_subclassing.py +469 -0
  602. numpy/ma/testutils.py +294 -0
  603. numpy/matlib.py +380 -0
  604. numpy/matlib.pyi +582 -0
  605. numpy/matrixlib/__init__.py +12 -0
  606. numpy/matrixlib/__init__.pyi +5 -0
  607. numpy/matrixlib/defmatrix.py +1119 -0
  608. numpy/matrixlib/defmatrix.pyi +17 -0
  609. numpy/matrixlib/tests/__init__.py +0 -0
  610. numpy/matrixlib/tests/test_defmatrix.py +455 -0
  611. numpy/matrixlib/tests/test_interaction.py +360 -0
  612. numpy/matrixlib/tests/test_masked_matrix.py +240 -0
  613. numpy/matrixlib/tests/test_matrix_linalg.py +105 -0
  614. numpy/matrixlib/tests/test_multiarray.py +17 -0
  615. numpy/matrixlib/tests/test_numeric.py +18 -0
  616. numpy/matrixlib/tests/test_regression.py +31 -0
  617. numpy/polynomial/__init__.py +187 -0
  618. numpy/polynomial/__init__.pyi +25 -0
  619. numpy/polynomial/_polybase.py +1191 -0
  620. numpy/polynomial/_polybase.pyi +285 -0
  621. numpy/polynomial/_polytypes.pyi +892 -0
  622. numpy/polynomial/chebyshev.py +2003 -0
  623. numpy/polynomial/chebyshev.pyi +181 -0
  624. numpy/polynomial/hermite.py +1740 -0
  625. numpy/polynomial/hermite.pyi +107 -0
  626. numpy/polynomial/hermite_e.py +1642 -0
  627. numpy/polynomial/hermite_e.pyi +107 -0
  628. numpy/polynomial/laguerre.py +1675 -0
  629. numpy/polynomial/laguerre.pyi +100 -0
  630. numpy/polynomial/legendre.py +1605 -0
  631. numpy/polynomial/legendre.pyi +100 -0
  632. numpy/polynomial/polynomial.py +1616 -0
  633. numpy/polynomial/polynomial.pyi +89 -0
  634. numpy/polynomial/polyutils.py +759 -0
  635. numpy/polynomial/polyutils.pyi +423 -0
  636. numpy/polynomial/tests/__init__.py +0 -0
  637. numpy/polynomial/tests/test_chebyshev.py +623 -0
  638. numpy/polynomial/tests/test_classes.py +618 -0
  639. numpy/polynomial/tests/test_hermite.py +558 -0
  640. numpy/polynomial/tests/test_hermite_e.py +559 -0
  641. numpy/polynomial/tests/test_laguerre.py +540 -0
  642. numpy/polynomial/tests/test_legendre.py +571 -0
  643. numpy/polynomial/tests/test_polynomial.py +669 -0
  644. numpy/polynomial/tests/test_polyutils.py +128 -0
  645. numpy/polynomial/tests/test_printing.py +555 -0
  646. numpy/polynomial/tests/test_symbol.py +217 -0
  647. numpy/py.typed +0 -0
  648. numpy/random/LICENSE.md +71 -0
  649. numpy/random/__init__.pxd +14 -0
  650. numpy/random/__init__.py +213 -0
  651. numpy/random/__init__.pyi +124 -0
  652. numpy/random/_bounded_integers.cpython-313-darwin.so +0 -0
  653. numpy/random/_bounded_integers.pxd +29 -0
  654. numpy/random/_bounded_integers.pyi +1 -0
  655. numpy/random/_common.cpython-313-darwin.so +0 -0
  656. numpy/random/_common.pxd +107 -0
  657. numpy/random/_common.pyi +16 -0
  658. numpy/random/_examples/cffi/extending.py +44 -0
  659. numpy/random/_examples/cffi/parse.py +53 -0
  660. numpy/random/_examples/cython/extending.pyx +77 -0
  661. numpy/random/_examples/cython/extending_distributions.pyx +118 -0
  662. numpy/random/_examples/cython/meson.build +53 -0
  663. numpy/random/_examples/numba/extending.py +86 -0
  664. numpy/random/_examples/numba/extending_distributions.py +67 -0
  665. numpy/random/_generator.cpython-313-darwin.so +0 -0
  666. numpy/random/_generator.pyi +861 -0
  667. numpy/random/_mt19937.cpython-313-darwin.so +0 -0
  668. numpy/random/_mt19937.pyi +25 -0
  669. numpy/random/_pcg64.cpython-313-darwin.so +0 -0
  670. numpy/random/_pcg64.pyi +44 -0
  671. numpy/random/_philox.cpython-313-darwin.so +0 -0
  672. numpy/random/_philox.pyi +39 -0
  673. numpy/random/_pickle.py +88 -0
  674. numpy/random/_pickle.pyi +43 -0
  675. numpy/random/_sfc64.cpython-313-darwin.so +0 -0
  676. numpy/random/_sfc64.pyi +28 -0
  677. numpy/random/bit_generator.cpython-313-darwin.so +0 -0
  678. numpy/random/bit_generator.pxd +35 -0
  679. numpy/random/bit_generator.pyi +124 -0
  680. numpy/random/c_distributions.pxd +119 -0
  681. numpy/random/lib/libnpyrandom.a +0 -0
  682. numpy/random/mtrand.cpython-313-darwin.so +0 -0
  683. numpy/random/mtrand.pyi +703 -0
  684. numpy/random/tests/__init__.py +0 -0
  685. numpy/random/tests/data/__init__.py +0 -0
  686. numpy/random/tests/data/generator_pcg64_np121.pkl.gz +0 -0
  687. numpy/random/tests/data/generator_pcg64_np126.pkl.gz +0 -0
  688. numpy/random/tests/data/mt19937-testset-1.csv +1001 -0
  689. numpy/random/tests/data/mt19937-testset-2.csv +1001 -0
  690. numpy/random/tests/data/pcg64-testset-1.csv +1001 -0
  691. numpy/random/tests/data/pcg64-testset-2.csv +1001 -0
  692. numpy/random/tests/data/pcg64dxsm-testset-1.csv +1001 -0
  693. numpy/random/tests/data/pcg64dxsm-testset-2.csv +1001 -0
  694. numpy/random/tests/data/philox-testset-1.csv +1001 -0
  695. numpy/random/tests/data/philox-testset-2.csv +1001 -0
  696. numpy/random/tests/data/sfc64-testset-1.csv +1001 -0
  697. numpy/random/tests/data/sfc64-testset-2.csv +1001 -0
  698. numpy/random/tests/data/sfc64_np126.pkl.gz +0 -0
  699. numpy/random/tests/test_direct.py +592 -0
  700. numpy/random/tests/test_extending.py +127 -0
  701. numpy/random/tests/test_generator_mt19937.py +2809 -0
  702. numpy/random/tests/test_generator_mt19937_regressions.py +207 -0
  703. numpy/random/tests/test_random.py +1757 -0
  704. numpy/random/tests/test_randomstate.py +2130 -0
  705. numpy/random/tests/test_randomstate_regression.py +217 -0
  706. numpy/random/tests/test_regression.py +152 -0
  707. numpy/random/tests/test_seed_sequence.py +79 -0
  708. numpy/random/tests/test_smoke.py +819 -0
  709. numpy/rec/__init__.py +2 -0
  710. numpy/rec/__init__.pyi +23 -0
  711. numpy/strings/__init__.py +2 -0
  712. numpy/strings/__init__.pyi +97 -0
  713. numpy/testing/__init__.py +22 -0
  714. numpy/testing/__init__.pyi +102 -0
  715. numpy/testing/_private/__init__.py +0 -0
  716. numpy/testing/_private/__init__.pyi +0 -0
  717. numpy/testing/_private/extbuild.py +250 -0
  718. numpy/testing/_private/extbuild.pyi +25 -0
  719. numpy/testing/_private/utils.py +2752 -0
  720. numpy/testing/_private/utils.pyi +499 -0
  721. numpy/testing/overrides.py +84 -0
  722. numpy/testing/overrides.pyi +11 -0
  723. numpy/testing/print_coercion_tables.py +207 -0
  724. numpy/testing/print_coercion_tables.pyi +27 -0
  725. numpy/testing/tests/__init__.py +0 -0
  726. numpy/testing/tests/test_utils.py +1917 -0
  727. numpy/tests/__init__.py +0 -0
  728. numpy/tests/test__all__.py +10 -0
  729. numpy/tests/test_configtool.py +48 -0
  730. numpy/tests/test_ctypeslib.py +377 -0
  731. numpy/tests/test_lazyloading.py +38 -0
  732. numpy/tests/test_matlib.py +59 -0
  733. numpy/tests/test_numpy_config.py +46 -0
  734. numpy/tests/test_numpy_version.py +54 -0
  735. numpy/tests/test_public_api.py +806 -0
  736. numpy/tests/test_reloading.py +74 -0
  737. numpy/tests/test_scripts.py +49 -0
  738. numpy/tests/test_warnings.py +78 -0
  739. numpy/typing/__init__.py +201 -0
  740. numpy/typing/mypy_plugin.py +195 -0
  741. numpy/typing/tests/__init__.py +0 -0
  742. numpy/typing/tests/data/fail/arithmetic.pyi +126 -0
  743. numpy/typing/tests/data/fail/array_constructors.pyi +34 -0
  744. numpy/typing/tests/data/fail/array_like.pyi +15 -0
  745. numpy/typing/tests/data/fail/array_pad.pyi +6 -0
  746. numpy/typing/tests/data/fail/arrayprint.pyi +16 -0
  747. numpy/typing/tests/data/fail/arrayterator.pyi +14 -0
  748. numpy/typing/tests/data/fail/bitwise_ops.pyi +17 -0
  749. numpy/typing/tests/data/fail/char.pyi +65 -0
  750. numpy/typing/tests/data/fail/chararray.pyi +62 -0
  751. numpy/typing/tests/data/fail/comparisons.pyi +27 -0
  752. numpy/typing/tests/data/fail/constants.pyi +3 -0
  753. numpy/typing/tests/data/fail/datasource.pyi +15 -0
  754. numpy/typing/tests/data/fail/dtype.pyi +17 -0
  755. numpy/typing/tests/data/fail/einsumfunc.pyi +12 -0
  756. numpy/typing/tests/data/fail/flatiter.pyi +20 -0
  757. numpy/typing/tests/data/fail/fromnumeric.pyi +148 -0
  758. numpy/typing/tests/data/fail/histograms.pyi +12 -0
  759. numpy/typing/tests/data/fail/index_tricks.pyi +14 -0
  760. numpy/typing/tests/data/fail/lib_function_base.pyi +62 -0
  761. numpy/typing/tests/data/fail/lib_polynomial.pyi +29 -0
  762. numpy/typing/tests/data/fail/lib_utils.pyi +3 -0
  763. numpy/typing/tests/data/fail/lib_version.pyi +6 -0
  764. numpy/typing/tests/data/fail/linalg.pyi +48 -0
  765. numpy/typing/tests/data/fail/ma.pyi +143 -0
  766. numpy/typing/tests/data/fail/memmap.pyi +5 -0
  767. numpy/typing/tests/data/fail/modules.pyi +17 -0
  768. numpy/typing/tests/data/fail/multiarray.pyi +52 -0
  769. numpy/typing/tests/data/fail/ndarray.pyi +11 -0
  770. numpy/typing/tests/data/fail/ndarray_misc.pyi +36 -0
  771. numpy/typing/tests/data/fail/nditer.pyi +8 -0
  772. numpy/typing/tests/data/fail/nested_sequence.pyi +16 -0
  773. numpy/typing/tests/data/fail/npyio.pyi +24 -0
  774. numpy/typing/tests/data/fail/numerictypes.pyi +5 -0
  775. numpy/typing/tests/data/fail/random.pyi +62 -0
  776. numpy/typing/tests/data/fail/rec.pyi +17 -0
  777. numpy/typing/tests/data/fail/scalars.pyi +87 -0
  778. numpy/typing/tests/data/fail/shape.pyi +6 -0
  779. numpy/typing/tests/data/fail/shape_base.pyi +8 -0
  780. numpy/typing/tests/data/fail/stride_tricks.pyi +9 -0
  781. numpy/typing/tests/data/fail/strings.pyi +52 -0
  782. numpy/typing/tests/data/fail/testing.pyi +28 -0
  783. numpy/typing/tests/data/fail/twodim_base.pyi +32 -0
  784. numpy/typing/tests/data/fail/type_check.pyi +13 -0
  785. numpy/typing/tests/data/fail/ufunc_config.pyi +21 -0
  786. numpy/typing/tests/data/fail/ufunclike.pyi +21 -0
  787. numpy/typing/tests/data/fail/ufuncs.pyi +17 -0
  788. numpy/typing/tests/data/fail/warnings_and_errors.pyi +5 -0
  789. numpy/typing/tests/data/misc/extended_precision.pyi +9 -0
  790. numpy/typing/tests/data/mypy.ini +9 -0
  791. numpy/typing/tests/data/pass/arithmetic.py +612 -0
  792. numpy/typing/tests/data/pass/array_constructors.py +137 -0
  793. numpy/typing/tests/data/pass/array_like.py +43 -0
  794. numpy/typing/tests/data/pass/arrayprint.py +37 -0
  795. numpy/typing/tests/data/pass/arrayterator.py +27 -0
  796. numpy/typing/tests/data/pass/bitwise_ops.py +131 -0
  797. numpy/typing/tests/data/pass/comparisons.py +315 -0
  798. numpy/typing/tests/data/pass/dtype.py +57 -0
  799. numpy/typing/tests/data/pass/einsumfunc.py +36 -0
  800. numpy/typing/tests/data/pass/flatiter.py +19 -0
  801. numpy/typing/tests/data/pass/fromnumeric.py +272 -0
  802. numpy/typing/tests/data/pass/index_tricks.py +60 -0
  803. numpy/typing/tests/data/pass/lib_user_array.py +22 -0
  804. numpy/typing/tests/data/pass/lib_utils.py +19 -0
  805. numpy/typing/tests/data/pass/lib_version.py +18 -0
  806. numpy/typing/tests/data/pass/literal.py +51 -0
  807. numpy/typing/tests/data/pass/ma.py +174 -0
  808. numpy/typing/tests/data/pass/mod.py +149 -0
  809. numpy/typing/tests/data/pass/modules.py +45 -0
  810. numpy/typing/tests/data/pass/multiarray.py +76 -0
  811. numpy/typing/tests/data/pass/ndarray_conversion.py +87 -0
  812. numpy/typing/tests/data/pass/ndarray_misc.py +203 -0
  813. numpy/typing/tests/data/pass/ndarray_shape_manipulation.py +47 -0
  814. numpy/typing/tests/data/pass/nditer.py +4 -0
  815. numpy/typing/tests/data/pass/numeric.py +95 -0
  816. numpy/typing/tests/data/pass/numerictypes.py +17 -0
  817. numpy/typing/tests/data/pass/random.py +1497 -0
  818. numpy/typing/tests/data/pass/recfunctions.py +161 -0
  819. numpy/typing/tests/data/pass/scalars.py +248 -0
  820. numpy/typing/tests/data/pass/shape.py +19 -0
  821. numpy/typing/tests/data/pass/simple.py +168 -0
  822. numpy/typing/tests/data/pass/simple_py3.py +6 -0
  823. numpy/typing/tests/data/pass/ufunc_config.py +64 -0
  824. numpy/typing/tests/data/pass/ufunclike.py +47 -0
  825. numpy/typing/tests/data/pass/ufuncs.py +16 -0
  826. numpy/typing/tests/data/pass/warnings_and_errors.py +6 -0
  827. numpy/typing/tests/data/reveal/arithmetic.pyi +720 -0
  828. numpy/typing/tests/data/reveal/array_api_info.pyi +70 -0
  829. numpy/typing/tests/data/reveal/array_constructors.pyi +249 -0
  830. numpy/typing/tests/data/reveal/arraypad.pyi +22 -0
  831. numpy/typing/tests/data/reveal/arrayprint.pyi +25 -0
  832. numpy/typing/tests/data/reveal/arraysetops.pyi +74 -0
  833. numpy/typing/tests/data/reveal/arrayterator.pyi +27 -0
  834. numpy/typing/tests/data/reveal/bitwise_ops.pyi +167 -0
  835. numpy/typing/tests/data/reveal/char.pyi +224 -0
  836. numpy/typing/tests/data/reveal/chararray.pyi +137 -0
  837. numpy/typing/tests/data/reveal/comparisons.pyi +264 -0
  838. numpy/typing/tests/data/reveal/constants.pyi +14 -0
  839. numpy/typing/tests/data/reveal/ctypeslib.pyi +81 -0
  840. numpy/typing/tests/data/reveal/datasource.pyi +23 -0
  841. numpy/typing/tests/data/reveal/dtype.pyi +136 -0
  842. numpy/typing/tests/data/reveal/einsumfunc.pyi +39 -0
  843. numpy/typing/tests/data/reveal/emath.pyi +54 -0
  844. numpy/typing/tests/data/reveal/fft.pyi +37 -0
  845. numpy/typing/tests/data/reveal/flatiter.pyi +47 -0
  846. numpy/typing/tests/data/reveal/fromnumeric.pyi +347 -0
  847. numpy/typing/tests/data/reveal/getlimits.pyi +51 -0
  848. numpy/typing/tests/data/reveal/histograms.pyi +25 -0
  849. numpy/typing/tests/data/reveal/index_tricks.pyi +70 -0
  850. numpy/typing/tests/data/reveal/lib_function_base.pyi +213 -0
  851. numpy/typing/tests/data/reveal/lib_polynomial.pyi +144 -0
  852. numpy/typing/tests/data/reveal/lib_utils.pyi +17 -0
  853. numpy/typing/tests/data/reveal/lib_version.pyi +20 -0
  854. numpy/typing/tests/data/reveal/linalg.pyi +132 -0
  855. numpy/typing/tests/data/reveal/ma.pyi +369 -0
  856. numpy/typing/tests/data/reveal/matrix.pyi +73 -0
  857. numpy/typing/tests/data/reveal/memmap.pyi +19 -0
  858. numpy/typing/tests/data/reveal/mod.pyi +179 -0
  859. numpy/typing/tests/data/reveal/modules.pyi +51 -0
  860. numpy/typing/tests/data/reveal/multiarray.pyi +194 -0
  861. numpy/typing/tests/data/reveal/nbit_base_example.pyi +21 -0
  862. numpy/typing/tests/data/reveal/ndarray_assignability.pyi +77 -0
  863. numpy/typing/tests/data/reveal/ndarray_conversion.pyi +85 -0
  864. numpy/typing/tests/data/reveal/ndarray_misc.pyi +247 -0
  865. numpy/typing/tests/data/reveal/ndarray_shape_manipulation.pyi +39 -0
  866. numpy/typing/tests/data/reveal/nditer.pyi +49 -0
  867. numpy/typing/tests/data/reveal/nested_sequence.pyi +25 -0
  868. numpy/typing/tests/data/reveal/npyio.pyi +83 -0
  869. numpy/typing/tests/data/reveal/numeric.pyi +134 -0
  870. numpy/typing/tests/data/reveal/numerictypes.pyi +16 -0
  871. numpy/typing/tests/data/reveal/polynomial_polybase.pyi +220 -0
  872. numpy/typing/tests/data/reveal/polynomial_polyutils.pyi +219 -0
  873. numpy/typing/tests/data/reveal/polynomial_series.pyi +138 -0
  874. numpy/typing/tests/data/reveal/random.pyi +1546 -0
  875. numpy/typing/tests/data/reveal/rec.pyi +171 -0
  876. numpy/typing/tests/data/reveal/scalars.pyi +191 -0
  877. numpy/typing/tests/data/reveal/shape.pyi +13 -0
  878. numpy/typing/tests/data/reveal/shape_base.pyi +52 -0
  879. numpy/typing/tests/data/reveal/stride_tricks.pyi +27 -0
  880. numpy/typing/tests/data/reveal/strings.pyi +196 -0
  881. numpy/typing/tests/data/reveal/testing.pyi +198 -0
  882. numpy/typing/tests/data/reveal/twodim_base.pyi +145 -0
  883. numpy/typing/tests/data/reveal/type_check.pyi +67 -0
  884. numpy/typing/tests/data/reveal/ufunc_config.pyi +30 -0
  885. numpy/typing/tests/data/reveal/ufunclike.pyi +31 -0
  886. numpy/typing/tests/data/reveal/ufuncs.pyi +123 -0
  887. numpy/typing/tests/data/reveal/warnings_and_errors.pyi +11 -0
  888. numpy/typing/tests/test_isfile.py +32 -0
  889. numpy/typing/tests/test_runtime.py +102 -0
  890. numpy/typing/tests/test_typing.py +205 -0
  891. numpy/version.py +11 -0
  892. numpy/version.pyi +18 -0
  893. numpy-2.3.5.dist-info/LICENSE.txt +971 -0
  894. numpy-2.3.5.dist-info/METADATA +1093 -0
  895. numpy-2.3.5.dist-info/RECORD +897 -0
  896. numpy-2.3.5.dist-info/WHEEL +6 -0
  897. numpy-2.3.5.dist-info/entry_points.txt +13 -0
@@ -0,0 +1,3682 @@
1
+ """Lite version of scipy.linalg.
2
+
3
+ Notes
4
+ -----
5
+ This module is a lite version of the linalg.py module in SciPy which
6
+ contains high-level Python interface to the LAPACK library. The lite
7
+ version only accesses the following LAPACK functions: dgesv, zgesv,
8
+ dgeev, zgeev, dgesdd, zgesdd, dgelsd, zgelsd, dsyevd, zheevd, dgetrf,
9
+ zgetrf, dpotrf, zpotrf, dgeqrf, zgeqrf, zungqr, dorgqr.
10
+ """
11
+
12
+ __all__ = ['matrix_power', 'solve', 'tensorsolve', 'tensorinv', 'inv',
13
+ 'cholesky', 'eigvals', 'eigvalsh', 'pinv', 'slogdet', 'det',
14
+ 'svd', 'svdvals', 'eig', 'eigh', 'lstsq', 'norm', 'qr', 'cond',
15
+ 'matrix_rank', 'LinAlgError', 'multi_dot', 'trace', 'diagonal',
16
+ 'cross', 'outer', 'tensordot', 'matmul', 'matrix_transpose',
17
+ 'matrix_norm', 'vector_norm', 'vecdot']
18
+
19
+ import functools
20
+ import operator
21
+ import warnings
22
+ from typing import Any, NamedTuple
23
+
24
+ from numpy._core import (
25
+ abs,
26
+ add,
27
+ all,
28
+ amax,
29
+ amin,
30
+ argsort,
31
+ array,
32
+ asanyarray,
33
+ asarray,
34
+ atleast_2d,
35
+ cdouble,
36
+ complexfloating,
37
+ count_nonzero,
38
+ csingle,
39
+ divide,
40
+ dot,
41
+ double,
42
+ empty,
43
+ empty_like,
44
+ errstate,
45
+ finfo,
46
+ inexact,
47
+ inf,
48
+ intc,
49
+ intp,
50
+ isfinite,
51
+ isnan,
52
+ moveaxis,
53
+ multiply,
54
+ newaxis,
55
+ object_,
56
+ overrides,
57
+ prod,
58
+ reciprocal,
59
+ sign,
60
+ single,
61
+ sort,
62
+ sqrt,
63
+ sum,
64
+ swapaxes,
65
+ zeros,
66
+ )
67
+ from numpy._core import (
68
+ cross as _core_cross,
69
+ )
70
+ from numpy._core import (
71
+ diagonal as _core_diagonal,
72
+ )
73
+ from numpy._core import (
74
+ matmul as _core_matmul,
75
+ )
76
+ from numpy._core import (
77
+ matrix_transpose as _core_matrix_transpose,
78
+ )
79
+ from numpy._core import (
80
+ outer as _core_outer,
81
+ )
82
+ from numpy._core import (
83
+ tensordot as _core_tensordot,
84
+ )
85
+ from numpy._core import (
86
+ trace as _core_trace,
87
+ )
88
+ from numpy._core import (
89
+ transpose as _core_transpose,
90
+ )
91
+ from numpy._core import (
92
+ vecdot as _core_vecdot,
93
+ )
94
+ from numpy._globals import _NoValue
95
+ from numpy._typing import NDArray
96
+ from numpy._utils import set_module
97
+ from numpy.lib._twodim_base_impl import eye, triu
98
+ from numpy.lib.array_utils import normalize_axis_index, normalize_axis_tuple
99
+ from numpy.linalg import _umath_linalg
100
+
101
+
102
+ class EigResult(NamedTuple):
103
+ eigenvalues: NDArray[Any]
104
+ eigenvectors: NDArray[Any]
105
+
106
+ class EighResult(NamedTuple):
107
+ eigenvalues: NDArray[Any]
108
+ eigenvectors: NDArray[Any]
109
+
110
+ class QRResult(NamedTuple):
111
+ Q: NDArray[Any]
112
+ R: NDArray[Any]
113
+
114
+ class SlogdetResult(NamedTuple):
115
+ sign: NDArray[Any]
116
+ logabsdet: NDArray[Any]
117
+
118
+ class SVDResult(NamedTuple):
119
+ U: NDArray[Any]
120
+ S: NDArray[Any]
121
+ Vh: NDArray[Any]
122
+
123
+
124
+ array_function_dispatch = functools.partial(
125
+ overrides.array_function_dispatch, module='numpy.linalg'
126
+ )
127
+
128
+
129
+ fortran_int = intc
130
+
131
+
132
+ @set_module('numpy.linalg')
133
+ class LinAlgError(ValueError):
134
+ """
135
+ Generic Python-exception-derived object raised by linalg functions.
136
+
137
+ General purpose exception class, derived from Python's ValueError
138
+ class, programmatically raised in linalg functions when a Linear
139
+ Algebra-related condition would prevent further correct execution of the
140
+ function.
141
+
142
+ Parameters
143
+ ----------
144
+ None
145
+
146
+ Examples
147
+ --------
148
+ >>> from numpy import linalg as LA
149
+ >>> LA.inv(np.zeros((2,2)))
150
+ Traceback (most recent call last):
151
+ File "<stdin>", line 1, in <module>
152
+ File "...linalg.py", line 350,
153
+ in inv return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
154
+ File "...linalg.py", line 249,
155
+ in solve
156
+ raise LinAlgError('Singular matrix')
157
+ numpy.linalg.LinAlgError: Singular matrix
158
+
159
+ """
160
+
161
+
162
+ def _raise_linalgerror_singular(err, flag):
163
+ raise LinAlgError("Singular matrix")
164
+
165
+ def _raise_linalgerror_nonposdef(err, flag):
166
+ raise LinAlgError("Matrix is not positive definite")
167
+
168
+ def _raise_linalgerror_eigenvalues_nonconvergence(err, flag):
169
+ raise LinAlgError("Eigenvalues did not converge")
170
+
171
+ def _raise_linalgerror_svd_nonconvergence(err, flag):
172
+ raise LinAlgError("SVD did not converge")
173
+
174
+ def _raise_linalgerror_lstsq(err, flag):
175
+ raise LinAlgError("SVD did not converge in Linear Least Squares")
176
+
177
+ def _raise_linalgerror_qr(err, flag):
178
+ raise LinAlgError("Incorrect argument found while performing "
179
+ "QR factorization")
180
+
181
+
182
+ def _makearray(a):
183
+ new = asarray(a)
184
+ wrap = getattr(a, "__array_wrap__", new.__array_wrap__)
185
+ return new, wrap
186
+
187
+ def isComplexType(t):
188
+ return issubclass(t, complexfloating)
189
+
190
+
191
+ _real_types_map = {single: single,
192
+ double: double,
193
+ csingle: single,
194
+ cdouble: double}
195
+
196
+ _complex_types_map = {single: csingle,
197
+ double: cdouble,
198
+ csingle: csingle,
199
+ cdouble: cdouble}
200
+
201
+ def _realType(t, default=double):
202
+ return _real_types_map.get(t, default)
203
+
204
+ def _complexType(t, default=cdouble):
205
+ return _complex_types_map.get(t, default)
206
+
207
+ def _commonType(*arrays):
208
+ # in lite version, use higher precision (always double or cdouble)
209
+ result_type = single
210
+ is_complex = False
211
+ for a in arrays:
212
+ type_ = a.dtype.type
213
+ if issubclass(type_, inexact):
214
+ if isComplexType(type_):
215
+ is_complex = True
216
+ rt = _realType(type_, default=None)
217
+ if rt is double:
218
+ result_type = double
219
+ elif rt is None:
220
+ # unsupported inexact scalar
221
+ raise TypeError(f"array type {a.dtype.name} is unsupported in linalg")
222
+ else:
223
+ result_type = double
224
+ if is_complex:
225
+ result_type = _complex_types_map[result_type]
226
+ return cdouble, result_type
227
+ else:
228
+ return double, result_type
229
+
230
+
231
+ def _to_native_byte_order(*arrays):
232
+ ret = []
233
+ for arr in arrays:
234
+ if arr.dtype.byteorder not in ('=', '|'):
235
+ ret.append(asarray(arr, dtype=arr.dtype.newbyteorder('=')))
236
+ else:
237
+ ret.append(arr)
238
+ if len(ret) == 1:
239
+ return ret[0]
240
+ else:
241
+ return ret
242
+
243
+
244
+ def _assert_2d(*arrays):
245
+ for a in arrays:
246
+ if a.ndim != 2:
247
+ raise LinAlgError('%d-dimensional array given. Array must be '
248
+ 'two-dimensional' % a.ndim)
249
+
250
+ def _assert_stacked_2d(*arrays):
251
+ for a in arrays:
252
+ if a.ndim < 2:
253
+ raise LinAlgError('%d-dimensional array given. Array must be '
254
+ 'at least two-dimensional' % a.ndim)
255
+
256
+ def _assert_stacked_square(*arrays):
257
+ for a in arrays:
258
+ try:
259
+ m, n = a.shape[-2:]
260
+ except ValueError:
261
+ raise LinAlgError('%d-dimensional array given. Array must be '
262
+ 'at least two-dimensional' % a.ndim)
263
+ if m != n:
264
+ raise LinAlgError('Last 2 dimensions of the array must be square')
265
+
266
+ def _assert_finite(*arrays):
267
+ for a in arrays:
268
+ if not isfinite(a).all():
269
+ raise LinAlgError("Array must not contain infs or NaNs")
270
+
271
+ def _is_empty_2d(arr):
272
+ # check size first for efficiency
273
+ return arr.size == 0 and prod(arr.shape[-2:]) == 0
274
+
275
+
276
+ def transpose(a):
277
+ """
278
+ Transpose each matrix in a stack of matrices.
279
+
280
+ Unlike np.transpose, this only swaps the last two axes, rather than all of
281
+ them
282
+
283
+ Parameters
284
+ ----------
285
+ a : (...,M,N) array_like
286
+
287
+ Returns
288
+ -------
289
+ aT : (...,N,M) ndarray
290
+ """
291
+ return swapaxes(a, -1, -2)
292
+
293
+ # Linear equations
294
+
295
+ def _tensorsolve_dispatcher(a, b, axes=None):
296
+ return (a, b)
297
+
298
+
299
+ @array_function_dispatch(_tensorsolve_dispatcher)
300
+ def tensorsolve(a, b, axes=None):
301
+ """
302
+ Solve the tensor equation ``a x = b`` for x.
303
+
304
+ It is assumed that all indices of `x` are summed over in the product,
305
+ together with the rightmost indices of `a`, as is done in, for example,
306
+ ``tensordot(a, x, axes=x.ndim)``.
307
+
308
+ Parameters
309
+ ----------
310
+ a : array_like
311
+ Coefficient tensor, of shape ``b.shape + Q``. `Q`, a tuple, equals
312
+ the shape of that sub-tensor of `a` consisting of the appropriate
313
+ number of its rightmost indices, and must be such that
314
+ ``prod(Q) == prod(b.shape)`` (in which sense `a` is said to be
315
+ 'square').
316
+ b : array_like
317
+ Right-hand tensor, which can be of any shape.
318
+ axes : tuple of ints, optional
319
+ Axes in `a` to reorder to the right, before inversion.
320
+ If None (default), no reordering is done.
321
+
322
+ Returns
323
+ -------
324
+ x : ndarray, shape Q
325
+
326
+ Raises
327
+ ------
328
+ LinAlgError
329
+ If `a` is singular or not 'square' (in the above sense).
330
+
331
+ See Also
332
+ --------
333
+ numpy.tensordot, tensorinv, numpy.einsum
334
+
335
+ Examples
336
+ --------
337
+ >>> import numpy as np
338
+ >>> a = np.eye(2*3*4)
339
+ >>> a.shape = (2*3, 4, 2, 3, 4)
340
+ >>> rng = np.random.default_rng()
341
+ >>> b = rng.normal(size=(2*3, 4))
342
+ >>> x = np.linalg.tensorsolve(a, b)
343
+ >>> x.shape
344
+ (2, 3, 4)
345
+ >>> np.allclose(np.tensordot(a, x, axes=3), b)
346
+ True
347
+
348
+ """
349
+ a, wrap = _makearray(a)
350
+ b = asarray(b)
351
+ an = a.ndim
352
+
353
+ if axes is not None:
354
+ allaxes = list(range(an))
355
+ for k in axes:
356
+ allaxes.remove(k)
357
+ allaxes.insert(an, k)
358
+ a = a.transpose(allaxes)
359
+
360
+ oldshape = a.shape[-(an - b.ndim):]
361
+ prod = 1
362
+ for k in oldshape:
363
+ prod *= k
364
+
365
+ if a.size != prod ** 2:
366
+ raise LinAlgError(
367
+ "Input arrays must satisfy the requirement \
368
+ prod(a.shape[b.ndim:]) == prod(a.shape[:b.ndim])"
369
+ )
370
+
371
+ a = a.reshape(prod, prod)
372
+ b = b.ravel()
373
+ res = wrap(solve(a, b))
374
+ res.shape = oldshape
375
+ return res
376
+
377
+
378
+ def _solve_dispatcher(a, b):
379
+ return (a, b)
380
+
381
+
382
+ @array_function_dispatch(_solve_dispatcher)
383
+ def solve(a, b):
384
+ """
385
+ Solve a linear matrix equation, or system of linear scalar equations.
386
+
387
+ Computes the "exact" solution, `x`, of the well-determined, i.e., full
388
+ rank, linear matrix equation `ax = b`.
389
+
390
+ Parameters
391
+ ----------
392
+ a : (..., M, M) array_like
393
+ Coefficient matrix.
394
+ b : {(M,), (..., M, K)}, array_like
395
+ Ordinate or "dependent variable" values.
396
+
397
+ Returns
398
+ -------
399
+ x : {(..., M,), (..., M, K)} ndarray
400
+ Solution to the system a x = b. Returned shape is (..., M) if b is
401
+ shape (M,) and (..., M, K) if b is (..., M, K), where the "..." part is
402
+ broadcasted between a and b.
403
+
404
+ Raises
405
+ ------
406
+ LinAlgError
407
+ If `a` is singular or not square.
408
+
409
+ See Also
410
+ --------
411
+ scipy.linalg.solve : Similar function in SciPy.
412
+
413
+ Notes
414
+ -----
415
+ Broadcasting rules apply, see the `numpy.linalg` documentation for
416
+ details.
417
+
418
+ The solutions are computed using LAPACK routine ``_gesv``.
419
+
420
+ `a` must be square and of full-rank, i.e., all rows (or, equivalently,
421
+ columns) must be linearly independent; if either is not true, use
422
+ `lstsq` for the least-squares best "solution" of the
423
+ system/equation.
424
+
425
+ .. versionchanged:: 2.0
426
+
427
+ The b array is only treated as a shape (M,) column vector if it is
428
+ exactly 1-dimensional. In all other instances it is treated as a stack
429
+ of (M, K) matrices. Previously b would be treated as a stack of (M,)
430
+ vectors if b.ndim was equal to a.ndim - 1.
431
+
432
+ References
433
+ ----------
434
+ .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
435
+ FL, Academic Press, Inc., 1980, pg. 22.
436
+
437
+ Examples
438
+ --------
439
+ Solve the system of equations:
440
+ ``x0 + 2 * x1 = 1`` and
441
+ ``3 * x0 + 5 * x1 = 2``:
442
+
443
+ >>> import numpy as np
444
+ >>> a = np.array([[1, 2], [3, 5]])
445
+ >>> b = np.array([1, 2])
446
+ >>> x = np.linalg.solve(a, b)
447
+ >>> x
448
+ array([-1., 1.])
449
+
450
+ Check that the solution is correct:
451
+
452
+ >>> np.allclose(np.dot(a, x), b)
453
+ True
454
+
455
+ """
456
+ a, _ = _makearray(a)
457
+ _assert_stacked_square(a)
458
+ b, wrap = _makearray(b)
459
+ t, result_t = _commonType(a, b)
460
+
461
+ # We use the b = (..., M,) logic, only if the number of extra dimensions
462
+ # match exactly
463
+ if b.ndim == 1:
464
+ gufunc = _umath_linalg.solve1
465
+ else:
466
+ gufunc = _umath_linalg.solve
467
+
468
+ signature = 'DD->D' if isComplexType(t) else 'dd->d'
469
+ with errstate(call=_raise_linalgerror_singular, invalid='call',
470
+ over='ignore', divide='ignore', under='ignore'):
471
+ r = gufunc(a, b, signature=signature)
472
+
473
+ return wrap(r.astype(result_t, copy=False))
474
+
475
+
476
+ def _tensorinv_dispatcher(a, ind=None):
477
+ return (a,)
478
+
479
+
480
+ @array_function_dispatch(_tensorinv_dispatcher)
481
+ def tensorinv(a, ind=2):
482
+ """
483
+ Compute the 'inverse' of an N-dimensional array.
484
+
485
+ The result is an inverse for `a` relative to the tensordot operation
486
+ ``tensordot(a, b, ind)``, i. e., up to floating-point accuracy,
487
+ ``tensordot(tensorinv(a), a, ind)`` is the "identity" tensor for the
488
+ tensordot operation.
489
+
490
+ Parameters
491
+ ----------
492
+ a : array_like
493
+ Tensor to 'invert'. Its shape must be 'square', i. e.,
494
+ ``prod(a.shape[:ind]) == prod(a.shape[ind:])``.
495
+ ind : int, optional
496
+ Number of first indices that are involved in the inverse sum.
497
+ Must be a positive integer, default is 2.
498
+
499
+ Returns
500
+ -------
501
+ b : ndarray
502
+ `a`'s tensordot inverse, shape ``a.shape[ind:] + a.shape[:ind]``.
503
+
504
+ Raises
505
+ ------
506
+ LinAlgError
507
+ If `a` is singular or not 'square' (in the above sense).
508
+
509
+ See Also
510
+ --------
511
+ numpy.tensordot, tensorsolve
512
+
513
+ Examples
514
+ --------
515
+ >>> import numpy as np
516
+ >>> a = np.eye(4*6)
517
+ >>> a.shape = (4, 6, 8, 3)
518
+ >>> ainv = np.linalg.tensorinv(a, ind=2)
519
+ >>> ainv.shape
520
+ (8, 3, 4, 6)
521
+ >>> rng = np.random.default_rng()
522
+ >>> b = rng.normal(size=(4, 6))
523
+ >>> np.allclose(np.tensordot(ainv, b), np.linalg.tensorsolve(a, b))
524
+ True
525
+
526
+ >>> a = np.eye(4*6)
527
+ >>> a.shape = (24, 8, 3)
528
+ >>> ainv = np.linalg.tensorinv(a, ind=1)
529
+ >>> ainv.shape
530
+ (8, 3, 24)
531
+ >>> rng = np.random.default_rng()
532
+ >>> b = rng.normal(size=24)
533
+ >>> np.allclose(np.tensordot(ainv, b, 1), np.linalg.tensorsolve(a, b))
534
+ True
535
+
536
+ """
537
+ a = asarray(a)
538
+ oldshape = a.shape
539
+ prod = 1
540
+ if ind > 0:
541
+ invshape = oldshape[ind:] + oldshape[:ind]
542
+ for k in oldshape[ind:]:
543
+ prod *= k
544
+ else:
545
+ raise ValueError("Invalid ind argument.")
546
+ a = a.reshape(prod, -1)
547
+ ia = inv(a)
548
+ return ia.reshape(*invshape)
549
+
550
+
551
+ # Matrix inversion
552
+
553
+ def _unary_dispatcher(a):
554
+ return (a,)
555
+
556
+
557
+ @array_function_dispatch(_unary_dispatcher)
558
+ def inv(a):
559
+ """
560
+ Compute the inverse of a matrix.
561
+
562
+ Given a square matrix `a`, return the matrix `ainv` satisfying
563
+ ``a @ ainv = ainv @ a = eye(a.shape[0])``.
564
+
565
+ Parameters
566
+ ----------
567
+ a : (..., M, M) array_like
568
+ Matrix to be inverted.
569
+
570
+ Returns
571
+ -------
572
+ ainv : (..., M, M) ndarray or matrix
573
+ Inverse of the matrix `a`.
574
+
575
+ Raises
576
+ ------
577
+ LinAlgError
578
+ If `a` is not square or inversion fails.
579
+
580
+ See Also
581
+ --------
582
+ scipy.linalg.inv : Similar function in SciPy.
583
+ numpy.linalg.cond : Compute the condition number of a matrix.
584
+ numpy.linalg.svd : Compute the singular value decomposition of a matrix.
585
+
586
+ Notes
587
+ -----
588
+ Broadcasting rules apply, see the `numpy.linalg` documentation for
589
+ details.
590
+
591
+ If `a` is detected to be singular, a `LinAlgError` is raised. If `a` is
592
+ ill-conditioned, a `LinAlgError` may or may not be raised, and results may
593
+ be inaccurate due to floating-point errors.
594
+
595
+ References
596
+ ----------
597
+ .. [1] Wikipedia, "Condition number",
598
+ https://en.wikipedia.org/wiki/Condition_number
599
+
600
+ Examples
601
+ --------
602
+ >>> import numpy as np
603
+ >>> from numpy.linalg import inv
604
+ >>> a = np.array([[1., 2.], [3., 4.]])
605
+ >>> ainv = inv(a)
606
+ >>> np.allclose(a @ ainv, np.eye(2))
607
+ True
608
+ >>> np.allclose(ainv @ a, np.eye(2))
609
+ True
610
+
611
+ If a is a matrix object, then the return value is a matrix as well:
612
+
613
+ >>> ainv = inv(np.matrix(a))
614
+ >>> ainv
615
+ matrix([[-2. , 1. ],
616
+ [ 1.5, -0.5]])
617
+
618
+ Inverses of several matrices can be computed at once:
619
+
620
+ >>> a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]])
621
+ >>> inv(a)
622
+ array([[[-2. , 1. ],
623
+ [ 1.5 , -0.5 ]],
624
+ [[-1.25, 0.75],
625
+ [ 0.75, -0.25]]])
626
+
627
+ If a matrix is close to singular, the computed inverse may not satisfy
628
+ ``a @ ainv = ainv @ a = eye(a.shape[0])`` even if a `LinAlgError`
629
+ is not raised:
630
+
631
+ >>> a = np.array([[2,4,6],[2,0,2],[6,8,14]])
632
+ >>> inv(a) # No errors raised
633
+ array([[-1.12589991e+15, -5.62949953e+14, 5.62949953e+14],
634
+ [-1.12589991e+15, -5.62949953e+14, 5.62949953e+14],
635
+ [ 1.12589991e+15, 5.62949953e+14, -5.62949953e+14]])
636
+ >>> a @ inv(a)
637
+ array([[ 0. , -0.5 , 0. ], # may vary
638
+ [-0.5 , 0.625, 0.25 ],
639
+ [ 0. , 0. , 1. ]])
640
+
641
+ To detect ill-conditioned matrices, you can use `numpy.linalg.cond` to
642
+ compute its *condition number* [1]_. The larger the condition number, the
643
+ more ill-conditioned the matrix is. As a rule of thumb, if the condition
644
+ number ``cond(a) = 10**k``, then you may lose up to ``k`` digits of
645
+ accuracy on top of what would be lost to the numerical method due to loss
646
+ of precision from arithmetic methods.
647
+
648
+ >>> from numpy.linalg import cond
649
+ >>> cond(a)
650
+ np.float64(8.659885634118668e+17) # may vary
651
+
652
+ It is also possible to detect ill-conditioning by inspecting the matrix's
653
+ singular values directly. The ratio between the largest and the smallest
654
+ singular value is the condition number:
655
+
656
+ >>> from numpy.linalg import svd
657
+ >>> sigma = svd(a, compute_uv=False) # Do not compute singular vectors
658
+ >>> sigma.max()/sigma.min()
659
+ 8.659885634118668e+17 # may vary
660
+
661
+ """
662
+ a, wrap = _makearray(a)
663
+ _assert_stacked_square(a)
664
+ t, result_t = _commonType(a)
665
+
666
+ signature = 'D->D' if isComplexType(t) else 'd->d'
667
+ with errstate(call=_raise_linalgerror_singular, invalid='call',
668
+ over='ignore', divide='ignore', under='ignore'):
669
+ ainv = _umath_linalg.inv(a, signature=signature)
670
+ return wrap(ainv.astype(result_t, copy=False))
671
+
672
+
673
+ def _matrix_power_dispatcher(a, n):
674
+ return (a,)
675
+
676
+
677
+ @array_function_dispatch(_matrix_power_dispatcher)
678
+ def matrix_power(a, n):
679
+ """
680
+ Raise a square matrix to the (integer) power `n`.
681
+
682
+ For positive integers `n`, the power is computed by repeated matrix
683
+ squarings and matrix multiplications. If ``n == 0``, the identity matrix
684
+ of the same shape as M is returned. If ``n < 0``, the inverse
685
+ is computed and then raised to the ``abs(n)``.
686
+
687
+ .. note:: Stacks of object matrices are not currently supported.
688
+
689
+ Parameters
690
+ ----------
691
+ a : (..., M, M) array_like
692
+ Matrix to be "powered".
693
+ n : int
694
+ The exponent can be any integer or long integer, positive,
695
+ negative, or zero.
696
+
697
+ Returns
698
+ -------
699
+ a**n : (..., M, M) ndarray or matrix object
700
+ The return value is the same shape and type as `M`;
701
+ if the exponent is positive or zero then the type of the
702
+ elements is the same as those of `M`. If the exponent is
703
+ negative the elements are floating-point.
704
+
705
+ Raises
706
+ ------
707
+ LinAlgError
708
+ For matrices that are not square or that (for negative powers) cannot
709
+ be inverted numerically.
710
+
711
+ Examples
712
+ --------
713
+ >>> import numpy as np
714
+ >>> from numpy.linalg import matrix_power
715
+ >>> i = np.array([[0, 1], [-1, 0]]) # matrix equiv. of the imaginary unit
716
+ >>> matrix_power(i, 3) # should = -i
717
+ array([[ 0, -1],
718
+ [ 1, 0]])
719
+ >>> matrix_power(i, 0)
720
+ array([[1, 0],
721
+ [0, 1]])
722
+ >>> matrix_power(i, -3) # should = 1/(-i) = i, but w/ f.p. elements
723
+ array([[ 0., 1.],
724
+ [-1., 0.]])
725
+
726
+ Somewhat more sophisticated example
727
+
728
+ >>> q = np.zeros((4, 4))
729
+ >>> q[0:2, 0:2] = -i
730
+ >>> q[2:4, 2:4] = i
731
+ >>> q # one of the three quaternion units not equal to 1
732
+ array([[ 0., -1., 0., 0.],
733
+ [ 1., 0., 0., 0.],
734
+ [ 0., 0., 0., 1.],
735
+ [ 0., 0., -1., 0.]])
736
+ >>> matrix_power(q, 2) # = -np.eye(4)
737
+ array([[-1., 0., 0., 0.],
738
+ [ 0., -1., 0., 0.],
739
+ [ 0., 0., -1., 0.],
740
+ [ 0., 0., 0., -1.]])
741
+
742
+ """
743
+ a = asanyarray(a)
744
+ _assert_stacked_square(a)
745
+
746
+ try:
747
+ n = operator.index(n)
748
+ except TypeError as e:
749
+ raise TypeError("exponent must be an integer") from e
750
+
751
+ # Fall back on dot for object arrays. Object arrays are not supported by
752
+ # the current implementation of matmul using einsum
753
+ if a.dtype != object:
754
+ fmatmul = matmul
755
+ elif a.ndim == 2:
756
+ fmatmul = dot
757
+ else:
758
+ raise NotImplementedError(
759
+ "matrix_power not supported for stacks of object arrays")
760
+
761
+ if n == 0:
762
+ a = empty_like(a)
763
+ a[...] = eye(a.shape[-2], dtype=a.dtype)
764
+ return a
765
+
766
+ elif n < 0:
767
+ a = inv(a)
768
+ n = abs(n)
769
+
770
+ # short-cuts.
771
+ if n == 1:
772
+ return a
773
+
774
+ elif n == 2:
775
+ return fmatmul(a, a)
776
+
777
+ elif n == 3:
778
+ return fmatmul(fmatmul(a, a), a)
779
+
780
+ # Use binary decomposition to reduce the number of matrix multiplications.
781
+ # Here, we iterate over the bits of n, from LSB to MSB, raise `a` to
782
+ # increasing powers of 2, and multiply into the result as needed.
783
+ z = result = None
784
+ while n > 0:
785
+ z = a if z is None else fmatmul(z, z)
786
+ n, bit = divmod(n, 2)
787
+ if bit:
788
+ result = z if result is None else fmatmul(result, z)
789
+
790
+ return result
791
+
792
+
793
+ # Cholesky decomposition
794
+
795
+ def _cholesky_dispatcher(a, /, *, upper=None):
796
+ return (a,)
797
+
798
+
799
+ @array_function_dispatch(_cholesky_dispatcher)
800
+ def cholesky(a, /, *, upper=False):
801
+ """
802
+ Cholesky decomposition.
803
+
804
+ Return the lower or upper Cholesky decomposition, ``L * L.H`` or
805
+ ``U.H * U``, of the square matrix ``a``, where ``L`` is lower-triangular,
806
+ ``U`` is upper-triangular, and ``.H`` is the conjugate transpose operator
807
+ (which is the ordinary transpose if ``a`` is real-valued). ``a`` must be
808
+ Hermitian (symmetric if real-valued) and positive-definite. No checking is
809
+ performed to verify whether ``a`` is Hermitian or not. In addition, only
810
+ the lower or upper-triangular and diagonal elements of ``a`` are used.
811
+ Only ``L`` or ``U`` is actually returned.
812
+
813
+ Parameters
814
+ ----------
815
+ a : (..., M, M) array_like
816
+ Hermitian (symmetric if all elements are real), positive-definite
817
+ input matrix.
818
+ upper : bool
819
+ If ``True``, the result must be the upper-triangular Cholesky factor.
820
+ If ``False``, the result must be the lower-triangular Cholesky factor.
821
+ Default: ``False``.
822
+
823
+ Returns
824
+ -------
825
+ L : (..., M, M) array_like
826
+ Lower or upper-triangular Cholesky factor of `a`. Returns a matrix
827
+ object if `a` is a matrix object.
828
+
829
+ Raises
830
+ ------
831
+ LinAlgError
832
+ If the decomposition fails, for example, if `a` is not
833
+ positive-definite.
834
+
835
+ See Also
836
+ --------
837
+ scipy.linalg.cholesky : Similar function in SciPy.
838
+ scipy.linalg.cholesky_banded : Cholesky decompose a banded Hermitian
839
+ positive-definite matrix.
840
+ scipy.linalg.cho_factor : Cholesky decomposition of a matrix, to use in
841
+ `scipy.linalg.cho_solve`.
842
+
843
+ Notes
844
+ -----
845
+ Broadcasting rules apply, see the `numpy.linalg` documentation for
846
+ details.
847
+
848
+ The Cholesky decomposition is often used as a fast way of solving
849
+
850
+ .. math:: A \\mathbf{x} = \\mathbf{b}
851
+
852
+ (when `A` is both Hermitian/symmetric and positive-definite).
853
+
854
+ First, we solve for :math:`\\mathbf{y}` in
855
+
856
+ .. math:: L \\mathbf{y} = \\mathbf{b},
857
+
858
+ and then for :math:`\\mathbf{x}` in
859
+
860
+ .. math:: L^{H} \\mathbf{x} = \\mathbf{y}.
861
+
862
+ Examples
863
+ --------
864
+ >>> import numpy as np
865
+ >>> A = np.array([[1,-2j],[2j,5]])
866
+ >>> A
867
+ array([[ 1.+0.j, -0.-2.j],
868
+ [ 0.+2.j, 5.+0.j]])
869
+ >>> L = np.linalg.cholesky(A)
870
+ >>> L
871
+ array([[1.+0.j, 0.+0.j],
872
+ [0.+2.j, 1.+0.j]])
873
+ >>> np.dot(L, L.T.conj()) # verify that L * L.H = A
874
+ array([[1.+0.j, 0.-2.j],
875
+ [0.+2.j, 5.+0.j]])
876
+ >>> A = [[1,-2j],[2j,5]] # what happens if A is only array_like?
877
+ >>> np.linalg.cholesky(A) # an ndarray object is returned
878
+ array([[1.+0.j, 0.+0.j],
879
+ [0.+2.j, 1.+0.j]])
880
+ >>> # But a matrix object is returned if A is a matrix object
881
+ >>> np.linalg.cholesky(np.matrix(A))
882
+ matrix([[ 1.+0.j, 0.+0.j],
883
+ [ 0.+2.j, 1.+0.j]])
884
+ >>> # The upper-triangular Cholesky factor can also be obtained.
885
+ >>> np.linalg.cholesky(A, upper=True)
886
+ array([[1.-0.j, 0.-2.j],
887
+ [0.-0.j, 1.-0.j]])
888
+
889
+ """
890
+ gufunc = _umath_linalg.cholesky_up if upper else _umath_linalg.cholesky_lo
891
+ a, wrap = _makearray(a)
892
+ _assert_stacked_square(a)
893
+ t, result_t = _commonType(a)
894
+ signature = 'D->D' if isComplexType(t) else 'd->d'
895
+ with errstate(call=_raise_linalgerror_nonposdef, invalid='call',
896
+ over='ignore', divide='ignore', under='ignore'):
897
+ r = gufunc(a, signature=signature)
898
+ return wrap(r.astype(result_t, copy=False))
899
+
900
+
901
+ # outer product
902
+
903
+
904
+ def _outer_dispatcher(x1, x2):
905
+ return (x1, x2)
906
+
907
+
908
+ @array_function_dispatch(_outer_dispatcher)
909
+ def outer(x1, x2, /):
910
+ """
911
+ Compute the outer product of two vectors.
912
+
913
+ This function is Array API compatible. Compared to ``np.outer``
914
+ it accepts 1-dimensional inputs only.
915
+
916
+ Parameters
917
+ ----------
918
+ x1 : (M,) array_like
919
+ One-dimensional input array of size ``N``.
920
+ Must have a numeric data type.
921
+ x2 : (N,) array_like
922
+ One-dimensional input array of size ``M``.
923
+ Must have a numeric data type.
924
+
925
+ Returns
926
+ -------
927
+ out : (M, N) ndarray
928
+ ``out[i, j] = a[i] * b[j]``
929
+
930
+ See also
931
+ --------
932
+ outer
933
+
934
+ Examples
935
+ --------
936
+ Make a (*very* coarse) grid for computing a Mandelbrot set:
937
+
938
+ >>> rl = np.linalg.outer(np.ones((5,)), np.linspace(-2, 2, 5))
939
+ >>> rl
940
+ array([[-2., -1., 0., 1., 2.],
941
+ [-2., -1., 0., 1., 2.],
942
+ [-2., -1., 0., 1., 2.],
943
+ [-2., -1., 0., 1., 2.],
944
+ [-2., -1., 0., 1., 2.]])
945
+ >>> im = np.linalg.outer(1j*np.linspace(2, -2, 5), np.ones((5,)))
946
+ >>> im
947
+ array([[0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j],
948
+ [0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j],
949
+ [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
950
+ [0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j],
951
+ [0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]])
952
+ >>> grid = rl + im
953
+ >>> grid
954
+ array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j],
955
+ [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j],
956
+ [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j],
957
+ [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j],
958
+ [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]])
959
+
960
+ An example using a "vector" of letters:
961
+
962
+ >>> x = np.array(['a', 'b', 'c'], dtype=object)
963
+ >>> np.linalg.outer(x, [1, 2, 3])
964
+ array([['a', 'aa', 'aaa'],
965
+ ['b', 'bb', 'bbb'],
966
+ ['c', 'cc', 'ccc']], dtype=object)
967
+
968
+ """
969
+ x1 = asanyarray(x1)
970
+ x2 = asanyarray(x2)
971
+ if x1.ndim != 1 or x2.ndim != 1:
972
+ raise ValueError(
973
+ "Input arrays must be one-dimensional, but they are "
974
+ f"{x1.ndim=} and {x2.ndim=}."
975
+ )
976
+ return _core_outer(x1, x2, out=None)
977
+
978
+
979
+ # QR decomposition
980
+
981
+
982
+ def _qr_dispatcher(a, mode=None):
983
+ return (a,)
984
+
985
+
986
+ @array_function_dispatch(_qr_dispatcher)
987
+ def qr(a, mode='reduced'):
988
+ """
989
+ Compute the qr factorization of a matrix.
990
+
991
+ Factor the matrix `a` as *qr*, where `q` is orthonormal and `r` is
992
+ upper-triangular.
993
+
994
+ Parameters
995
+ ----------
996
+ a : array_like, shape (..., M, N)
997
+ An array-like object with the dimensionality of at least 2.
998
+ mode : {'reduced', 'complete', 'r', 'raw'}, optional, default: 'reduced'
999
+ If K = min(M, N), then
1000
+
1001
+ * 'reduced' : returns Q, R with dimensions (..., M, K), (..., K, N)
1002
+ * 'complete' : returns Q, R with dimensions (..., M, M), (..., M, N)
1003
+ * 'r' : returns R only with dimensions (..., K, N)
1004
+ * 'raw' : returns h, tau with dimensions (..., N, M), (..., K,)
1005
+
1006
+ The options 'reduced', 'complete, and 'raw' are new in numpy 1.8,
1007
+ see the notes for more information. The default is 'reduced', and to
1008
+ maintain backward compatibility with earlier versions of numpy both
1009
+ it and the old default 'full' can be omitted. Note that array h
1010
+ returned in 'raw' mode is transposed for calling Fortran. The
1011
+ 'economic' mode is deprecated. The modes 'full' and 'economic' may
1012
+ be passed using only the first letter for backwards compatibility,
1013
+ but all others must be spelled out. See the Notes for more
1014
+ explanation.
1015
+
1016
+
1017
+ Returns
1018
+ -------
1019
+ When mode is 'reduced' or 'complete', the result will be a namedtuple with
1020
+ the attributes `Q` and `R`.
1021
+
1022
+ Q : ndarray of float or complex, optional
1023
+ A matrix with orthonormal columns. When mode = 'complete' the
1024
+ result is an orthogonal/unitary matrix depending on whether or not
1025
+ a is real/complex. The determinant may be either +/- 1 in that
1026
+ case. In case the number of dimensions in the input array is
1027
+ greater than 2 then a stack of the matrices with above properties
1028
+ is returned.
1029
+ R : ndarray of float or complex, optional
1030
+ The upper-triangular matrix or a stack of upper-triangular
1031
+ matrices if the number of dimensions in the input array is greater
1032
+ than 2.
1033
+ (h, tau) : ndarrays of np.double or np.cdouble, optional
1034
+ The array h contains the Householder reflectors that generate q
1035
+ along with r. The tau array contains scaling factors for the
1036
+ reflectors. In the deprecated 'economic' mode only h is returned.
1037
+
1038
+ Raises
1039
+ ------
1040
+ LinAlgError
1041
+ If factoring fails.
1042
+
1043
+ See Also
1044
+ --------
1045
+ scipy.linalg.qr : Similar function in SciPy.
1046
+ scipy.linalg.rq : Compute RQ decomposition of a matrix.
1047
+
1048
+ Notes
1049
+ -----
1050
+ This is an interface to the LAPACK routines ``dgeqrf``, ``zgeqrf``,
1051
+ ``dorgqr``, and ``zungqr``.
1052
+
1053
+ For more information on the qr factorization, see for example:
1054
+ https://en.wikipedia.org/wiki/QR_factorization
1055
+
1056
+ Subclasses of `ndarray` are preserved except for the 'raw' mode. So if
1057
+ `a` is of type `matrix`, all the return values will be matrices too.
1058
+
1059
+ New 'reduced', 'complete', and 'raw' options for mode were added in
1060
+ NumPy 1.8.0 and the old option 'full' was made an alias of 'reduced'. In
1061
+ addition the options 'full' and 'economic' were deprecated. Because
1062
+ 'full' was the previous default and 'reduced' is the new default,
1063
+ backward compatibility can be maintained by letting `mode` default.
1064
+ The 'raw' option was added so that LAPACK routines that can multiply
1065
+ arrays by q using the Householder reflectors can be used. Note that in
1066
+ this case the returned arrays are of type np.double or np.cdouble and
1067
+ the h array is transposed to be FORTRAN compatible. No routines using
1068
+ the 'raw' return are currently exposed by numpy, but some are available
1069
+ in lapack_lite and just await the necessary work.
1070
+
1071
+ Examples
1072
+ --------
1073
+ >>> import numpy as np
1074
+ >>> rng = np.random.default_rng()
1075
+ >>> a = rng.normal(size=(9, 6))
1076
+ >>> Q, R = np.linalg.qr(a)
1077
+ >>> np.allclose(a, np.dot(Q, R)) # a does equal QR
1078
+ True
1079
+ >>> R2 = np.linalg.qr(a, mode='r')
1080
+ >>> np.allclose(R, R2) # mode='r' returns the same R as mode='full'
1081
+ True
1082
+ >>> a = np.random.normal(size=(3, 2, 2)) # Stack of 2 x 2 matrices as input
1083
+ >>> Q, R = np.linalg.qr(a)
1084
+ >>> Q.shape
1085
+ (3, 2, 2)
1086
+ >>> R.shape
1087
+ (3, 2, 2)
1088
+ >>> np.allclose(a, np.matmul(Q, R))
1089
+ True
1090
+
1091
+ Example illustrating a common use of `qr`: solving of least squares
1092
+ problems
1093
+
1094
+ What are the least-squares-best `m` and `y0` in ``y = y0 + mx`` for
1095
+ the following data: {(0,1), (1,0), (1,2), (2,1)}. (Graph the points
1096
+ and you'll see that it should be y0 = 0, m = 1.) The answer is provided
1097
+ by solving the over-determined matrix equation ``Ax = b``, where::
1098
+
1099
+ A = array([[0, 1], [1, 1], [1, 1], [2, 1]])
1100
+ x = array([[y0], [m]])
1101
+ b = array([[1], [0], [2], [1]])
1102
+
1103
+ If A = QR such that Q is orthonormal (which is always possible via
1104
+ Gram-Schmidt), then ``x = inv(R) * (Q.T) * b``. (In numpy practice,
1105
+ however, we simply use `lstsq`.)
1106
+
1107
+ >>> A = np.array([[0, 1], [1, 1], [1, 1], [2, 1]])
1108
+ >>> A
1109
+ array([[0, 1],
1110
+ [1, 1],
1111
+ [1, 1],
1112
+ [2, 1]])
1113
+ >>> b = np.array([1, 2, 2, 3])
1114
+ >>> Q, R = np.linalg.qr(A)
1115
+ >>> p = np.dot(Q.T, b)
1116
+ >>> np.dot(np.linalg.inv(R), p)
1117
+ array([ 1., 1.])
1118
+
1119
+ """
1120
+ if mode not in ('reduced', 'complete', 'r', 'raw'):
1121
+ if mode in ('f', 'full'):
1122
+ # 2013-04-01, 1.8
1123
+ msg = (
1124
+ "The 'full' option is deprecated in favor of 'reduced'.\n"
1125
+ "For backward compatibility let mode default."
1126
+ )
1127
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
1128
+ mode = 'reduced'
1129
+ elif mode in ('e', 'economic'):
1130
+ # 2013-04-01, 1.8
1131
+ msg = "The 'economic' option is deprecated."
1132
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
1133
+ mode = 'economic'
1134
+ else:
1135
+ raise ValueError(f"Unrecognized mode '{mode}'")
1136
+
1137
+ a, wrap = _makearray(a)
1138
+ _assert_stacked_2d(a)
1139
+ m, n = a.shape[-2:]
1140
+ t, result_t = _commonType(a)
1141
+ a = a.astype(t, copy=True)
1142
+ a = _to_native_byte_order(a)
1143
+ mn = min(m, n)
1144
+
1145
+ signature = 'D->D' if isComplexType(t) else 'd->d'
1146
+ with errstate(call=_raise_linalgerror_qr, invalid='call',
1147
+ over='ignore', divide='ignore', under='ignore'):
1148
+ tau = _umath_linalg.qr_r_raw(a, signature=signature)
1149
+
1150
+ # handle modes that don't return q
1151
+ if mode == 'r':
1152
+ r = triu(a[..., :mn, :])
1153
+ r = r.astype(result_t, copy=False)
1154
+ return wrap(r)
1155
+
1156
+ if mode == 'raw':
1157
+ q = transpose(a)
1158
+ q = q.astype(result_t, copy=False)
1159
+ tau = tau.astype(result_t, copy=False)
1160
+ return wrap(q), tau
1161
+
1162
+ if mode == 'economic':
1163
+ a = a.astype(result_t, copy=False)
1164
+ return wrap(a)
1165
+
1166
+ # mc is the number of columns in the resulting q
1167
+ # matrix. If the mode is complete then it is
1168
+ # same as number of rows, and if the mode is reduced,
1169
+ # then it is the minimum of number of rows and columns.
1170
+ if mode == 'complete' and m > n:
1171
+ mc = m
1172
+ gufunc = _umath_linalg.qr_complete
1173
+ else:
1174
+ mc = mn
1175
+ gufunc = _umath_linalg.qr_reduced
1176
+
1177
+ signature = 'DD->D' if isComplexType(t) else 'dd->d'
1178
+ with errstate(call=_raise_linalgerror_qr, invalid='call',
1179
+ over='ignore', divide='ignore', under='ignore'):
1180
+ q = gufunc(a, tau, signature=signature)
1181
+ r = triu(a[..., :mc, :])
1182
+
1183
+ q = q.astype(result_t, copy=False)
1184
+ r = r.astype(result_t, copy=False)
1185
+
1186
+ return QRResult(wrap(q), wrap(r))
1187
+
1188
+ # Eigenvalues
1189
+
1190
+
1191
+ @array_function_dispatch(_unary_dispatcher)
1192
+ def eigvals(a):
1193
+ """
1194
+ Compute the eigenvalues of a general matrix.
1195
+
1196
+ Main difference between `eigvals` and `eig`: the eigenvectors aren't
1197
+ returned.
1198
+
1199
+ Parameters
1200
+ ----------
1201
+ a : (..., M, M) array_like
1202
+ A complex- or real-valued matrix whose eigenvalues will be computed.
1203
+
1204
+ Returns
1205
+ -------
1206
+ w : (..., M,) ndarray
1207
+ The eigenvalues, each repeated according to its multiplicity.
1208
+ They are not necessarily ordered, nor are they necessarily
1209
+ real for real matrices.
1210
+
1211
+ Raises
1212
+ ------
1213
+ LinAlgError
1214
+ If the eigenvalue computation does not converge.
1215
+
1216
+ See Also
1217
+ --------
1218
+ eig : eigenvalues and right eigenvectors of general arrays
1219
+ eigvalsh : eigenvalues of real symmetric or complex Hermitian
1220
+ (conjugate symmetric) arrays.
1221
+ eigh : eigenvalues and eigenvectors of real symmetric or complex
1222
+ Hermitian (conjugate symmetric) arrays.
1223
+ scipy.linalg.eigvals : Similar function in SciPy.
1224
+
1225
+ Notes
1226
+ -----
1227
+ Broadcasting rules apply, see the `numpy.linalg` documentation for
1228
+ details.
1229
+
1230
+ This is implemented using the ``_geev`` LAPACK routines which compute
1231
+ the eigenvalues and eigenvectors of general square arrays.
1232
+
1233
+ Examples
1234
+ --------
1235
+ Illustration, using the fact that the eigenvalues of a diagonal matrix
1236
+ are its diagonal elements, that multiplying a matrix on the left
1237
+ by an orthogonal matrix, `Q`, and on the right by `Q.T` (the transpose
1238
+ of `Q`), preserves the eigenvalues of the "middle" matrix. In other words,
1239
+ if `Q` is orthogonal, then ``Q * A * Q.T`` has the same eigenvalues as
1240
+ ``A``:
1241
+
1242
+ >>> import numpy as np
1243
+ >>> from numpy import linalg as LA
1244
+ >>> x = np.random.random()
1245
+ >>> Q = np.array([[np.cos(x), -np.sin(x)], [np.sin(x), np.cos(x)]])
1246
+ >>> LA.norm(Q[0, :]), LA.norm(Q[1, :]), np.dot(Q[0, :],Q[1, :])
1247
+ (1.0, 1.0, 0.0)
1248
+
1249
+ Now multiply a diagonal matrix by ``Q`` on one side and
1250
+ by ``Q.T`` on the other:
1251
+
1252
+ >>> D = np.diag((-1,1))
1253
+ >>> LA.eigvals(D)
1254
+ array([-1., 1.])
1255
+ >>> A = np.dot(Q, D)
1256
+ >>> A = np.dot(A, Q.T)
1257
+ >>> LA.eigvals(A)
1258
+ array([ 1., -1.]) # random
1259
+
1260
+ """
1261
+ a, wrap = _makearray(a)
1262
+ _assert_stacked_square(a)
1263
+ _assert_finite(a)
1264
+ t, result_t = _commonType(a)
1265
+
1266
+ signature = 'D->D' if isComplexType(t) else 'd->D'
1267
+ with errstate(call=_raise_linalgerror_eigenvalues_nonconvergence,
1268
+ invalid='call', over='ignore', divide='ignore',
1269
+ under='ignore'):
1270
+ w = _umath_linalg.eigvals(a, signature=signature)
1271
+
1272
+ if not isComplexType(t):
1273
+ if all(w.imag == 0):
1274
+ w = w.real
1275
+ result_t = _realType(result_t)
1276
+ else:
1277
+ result_t = _complexType(result_t)
1278
+
1279
+ return w.astype(result_t, copy=False)
1280
+
1281
+
1282
+ def _eigvalsh_dispatcher(a, UPLO=None):
1283
+ return (a,)
1284
+
1285
+
1286
+ @array_function_dispatch(_eigvalsh_dispatcher)
1287
+ def eigvalsh(a, UPLO='L'):
1288
+ """
1289
+ Compute the eigenvalues of a complex Hermitian or real symmetric matrix.
1290
+
1291
+ Main difference from eigh: the eigenvectors are not computed.
1292
+
1293
+ Parameters
1294
+ ----------
1295
+ a : (..., M, M) array_like
1296
+ A complex- or real-valued matrix whose eigenvalues are to be
1297
+ computed.
1298
+ UPLO : {'L', 'U'}, optional
1299
+ Specifies whether the calculation is done with the lower triangular
1300
+ part of `a` ('L', default) or the upper triangular part ('U').
1301
+ Irrespective of this value only the real parts of the diagonal will
1302
+ be considered in the computation to preserve the notion of a Hermitian
1303
+ matrix. It therefore follows that the imaginary part of the diagonal
1304
+ will always be treated as zero.
1305
+
1306
+ Returns
1307
+ -------
1308
+ w : (..., M,) ndarray
1309
+ The eigenvalues in ascending order, each repeated according to
1310
+ its multiplicity.
1311
+
1312
+ Raises
1313
+ ------
1314
+ LinAlgError
1315
+ If the eigenvalue computation does not converge.
1316
+
1317
+ See Also
1318
+ --------
1319
+ eigh : eigenvalues and eigenvectors of real symmetric or complex Hermitian
1320
+ (conjugate symmetric) arrays.
1321
+ eigvals : eigenvalues of general real or complex arrays.
1322
+ eig : eigenvalues and right eigenvectors of general real or complex
1323
+ arrays.
1324
+ scipy.linalg.eigvalsh : Similar function in SciPy.
1325
+
1326
+ Notes
1327
+ -----
1328
+ Broadcasting rules apply, see the `numpy.linalg` documentation for
1329
+ details.
1330
+
1331
+ The eigenvalues are computed using LAPACK routines ``_syevd``, ``_heevd``.
1332
+
1333
+ Examples
1334
+ --------
1335
+ >>> import numpy as np
1336
+ >>> from numpy import linalg as LA
1337
+ >>> a = np.array([[1, -2j], [2j, 5]])
1338
+ >>> LA.eigvalsh(a)
1339
+ array([ 0.17157288, 5.82842712]) # may vary
1340
+
1341
+ >>> # demonstrate the treatment of the imaginary part of the diagonal
1342
+ >>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]])
1343
+ >>> a
1344
+ array([[5.+2.j, 9.-2.j],
1345
+ [0.+2.j, 2.-1.j]])
1346
+ >>> # with UPLO='L' this is numerically equivalent to using LA.eigvals()
1347
+ >>> # with:
1348
+ >>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]])
1349
+ >>> b
1350
+ array([[5.+0.j, 0.-2.j],
1351
+ [0.+2.j, 2.+0.j]])
1352
+ >>> wa = LA.eigvalsh(a)
1353
+ >>> wb = LA.eigvals(b)
1354
+ >>> wa
1355
+ array([1., 6.])
1356
+ >>> wb
1357
+ array([6.+0.j, 1.+0.j])
1358
+
1359
+ """
1360
+ UPLO = UPLO.upper()
1361
+ if UPLO not in ('L', 'U'):
1362
+ raise ValueError("UPLO argument must be 'L' or 'U'")
1363
+
1364
+ if UPLO == 'L':
1365
+ gufunc = _umath_linalg.eigvalsh_lo
1366
+ else:
1367
+ gufunc = _umath_linalg.eigvalsh_up
1368
+
1369
+ a, wrap = _makearray(a)
1370
+ _assert_stacked_square(a)
1371
+ t, result_t = _commonType(a)
1372
+ signature = 'D->d' if isComplexType(t) else 'd->d'
1373
+ with errstate(call=_raise_linalgerror_eigenvalues_nonconvergence,
1374
+ invalid='call', over='ignore', divide='ignore',
1375
+ under='ignore'):
1376
+ w = gufunc(a, signature=signature)
1377
+ return w.astype(_realType(result_t), copy=False)
1378
+
1379
+
1380
+ # Eigenvectors
1381
+
1382
+
1383
+ @array_function_dispatch(_unary_dispatcher)
1384
+ def eig(a):
1385
+ """
1386
+ Compute the eigenvalues and right eigenvectors of a square array.
1387
+
1388
+ Parameters
1389
+ ----------
1390
+ a : (..., M, M) array
1391
+ Matrices for which the eigenvalues and right eigenvectors will
1392
+ be computed
1393
+
1394
+ Returns
1395
+ -------
1396
+ A namedtuple with the following attributes:
1397
+
1398
+ eigenvalues : (..., M) array
1399
+ The eigenvalues, each repeated according to its multiplicity.
1400
+ The eigenvalues are not necessarily ordered. The resulting
1401
+ array will be of complex type, unless the imaginary part is
1402
+ zero in which case it will be cast to a real type. When `a`
1403
+ is real the resulting eigenvalues will be real (0 imaginary
1404
+ part) or occur in conjugate pairs
1405
+
1406
+ eigenvectors : (..., M, M) array
1407
+ The normalized (unit "length") eigenvectors, such that the
1408
+ column ``eigenvectors[:,i]`` is the eigenvector corresponding to the
1409
+ eigenvalue ``eigenvalues[i]``.
1410
+
1411
+ Raises
1412
+ ------
1413
+ LinAlgError
1414
+ If the eigenvalue computation does not converge.
1415
+
1416
+ See Also
1417
+ --------
1418
+ eigvals : eigenvalues of a non-symmetric array.
1419
+ eigh : eigenvalues and eigenvectors of a real symmetric or complex
1420
+ Hermitian (conjugate symmetric) array.
1421
+ eigvalsh : eigenvalues of a real symmetric or complex Hermitian
1422
+ (conjugate symmetric) array.
1423
+ scipy.linalg.eig : Similar function in SciPy that also solves the
1424
+ generalized eigenvalue problem.
1425
+ scipy.linalg.schur : Best choice for unitary and other non-Hermitian
1426
+ normal matrices.
1427
+
1428
+ Notes
1429
+ -----
1430
+ Broadcasting rules apply, see the `numpy.linalg` documentation for
1431
+ details.
1432
+
1433
+ This is implemented using the ``_geev`` LAPACK routines which compute
1434
+ the eigenvalues and eigenvectors of general square arrays.
1435
+
1436
+ The number `w` is an eigenvalue of `a` if there exists a vector `v` such
1437
+ that ``a @ v = w * v``. Thus, the arrays `a`, `eigenvalues`, and
1438
+ `eigenvectors` satisfy the equations ``a @ eigenvectors[:,i] =
1439
+ eigenvalues[i] * eigenvectors[:,i]`` for :math:`i \\in \\{0,...,M-1\\}`.
1440
+
1441
+ The array `eigenvectors` may not be of maximum rank, that is, some of the
1442
+ columns may be linearly dependent, although round-off error may obscure
1443
+ that fact. If the eigenvalues are all different, then theoretically the
1444
+ eigenvectors are linearly independent and `a` can be diagonalized by a
1445
+ similarity transformation using `eigenvectors`, i.e, ``inv(eigenvectors) @
1446
+ a @ eigenvectors`` is diagonal.
1447
+
1448
+ For non-Hermitian normal matrices the SciPy function `scipy.linalg.schur`
1449
+ is preferred because the matrix `eigenvectors` is guaranteed to be
1450
+ unitary, which is not the case when using `eig`. The Schur factorization
1451
+ produces an upper triangular matrix rather than a diagonal matrix, but for
1452
+ normal matrices only the diagonal of the upper triangular matrix is
1453
+ needed, the rest is roundoff error.
1454
+
1455
+ Finally, it is emphasized that `eigenvectors` consists of the *right* (as
1456
+ in right-hand side) eigenvectors of `a`. A vector `y` satisfying ``y.T @ a
1457
+ = z * y.T`` for some number `z` is called a *left* eigenvector of `a`,
1458
+ and, in general, the left and right eigenvectors of a matrix are not
1459
+ necessarily the (perhaps conjugate) transposes of each other.
1460
+
1461
+ References
1462
+ ----------
1463
+ G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, FL,
1464
+ Academic Press, Inc., 1980, Various pp.
1465
+
1466
+ Examples
1467
+ --------
1468
+ >>> import numpy as np
1469
+ >>> from numpy import linalg as LA
1470
+
1471
+ (Almost) trivial example with real eigenvalues and eigenvectors.
1472
+
1473
+ >>> eigenvalues, eigenvectors = LA.eig(np.diag((1, 2, 3)))
1474
+ >>> eigenvalues
1475
+ array([1., 2., 3.])
1476
+ >>> eigenvectors
1477
+ array([[1., 0., 0.],
1478
+ [0., 1., 0.],
1479
+ [0., 0., 1.]])
1480
+
1481
+ Real matrix possessing complex eigenvalues and eigenvectors;
1482
+ note that the eigenvalues are complex conjugates of each other.
1483
+
1484
+ >>> eigenvalues, eigenvectors = LA.eig(np.array([[1, -1], [1, 1]]))
1485
+ >>> eigenvalues
1486
+ array([1.+1.j, 1.-1.j])
1487
+ >>> eigenvectors
1488
+ array([[0.70710678+0.j , 0.70710678-0.j ],
1489
+ [0. -0.70710678j, 0. +0.70710678j]])
1490
+
1491
+ Complex-valued matrix with real eigenvalues (but complex-valued
1492
+ eigenvectors); note that ``a.conj().T == a``, i.e., `a` is Hermitian.
1493
+
1494
+ >>> a = np.array([[1, 1j], [-1j, 1]])
1495
+ >>> eigenvalues, eigenvectors = LA.eig(a)
1496
+ >>> eigenvalues
1497
+ array([2.+0.j, 0.+0.j])
1498
+ >>> eigenvectors
1499
+ array([[ 0. +0.70710678j, 0.70710678+0.j ], # may vary
1500
+ [ 0.70710678+0.j , -0. +0.70710678j]])
1501
+
1502
+ Be careful about round-off error!
1503
+
1504
+ >>> a = np.array([[1 + 1e-9, 0], [0, 1 - 1e-9]])
1505
+ >>> # Theor. eigenvalues are 1 +/- 1e-9
1506
+ >>> eigenvalues, eigenvectors = LA.eig(a)
1507
+ >>> eigenvalues
1508
+ array([1., 1.])
1509
+ >>> eigenvectors
1510
+ array([[1., 0.],
1511
+ [0., 1.]])
1512
+
1513
+ """
1514
+ a, wrap = _makearray(a)
1515
+ _assert_stacked_square(a)
1516
+ _assert_finite(a)
1517
+ t, result_t = _commonType(a)
1518
+
1519
+ signature = 'D->DD' if isComplexType(t) else 'd->DD'
1520
+ with errstate(call=_raise_linalgerror_eigenvalues_nonconvergence,
1521
+ invalid='call', over='ignore', divide='ignore',
1522
+ under='ignore'):
1523
+ w, vt = _umath_linalg.eig(a, signature=signature)
1524
+
1525
+ if not isComplexType(t) and all(w.imag == 0.0):
1526
+ w = w.real
1527
+ vt = vt.real
1528
+ result_t = _realType(result_t)
1529
+ else:
1530
+ result_t = _complexType(result_t)
1531
+
1532
+ vt = vt.astype(result_t, copy=False)
1533
+ return EigResult(w.astype(result_t, copy=False), wrap(vt))
1534
+
1535
+
1536
+ @array_function_dispatch(_eigvalsh_dispatcher)
1537
+ def eigh(a, UPLO='L'):
1538
+ """
1539
+ Return the eigenvalues and eigenvectors of a complex Hermitian
1540
+ (conjugate symmetric) or a real symmetric matrix.
1541
+
1542
+ Returns two objects, a 1-D array containing the eigenvalues of `a`, and
1543
+ a 2-D square array or matrix (depending on the input type) of the
1544
+ corresponding eigenvectors (in columns).
1545
+
1546
+ Parameters
1547
+ ----------
1548
+ a : (..., M, M) array
1549
+ Hermitian or real symmetric matrices whose eigenvalues and
1550
+ eigenvectors are to be computed.
1551
+ UPLO : {'L', 'U'}, optional
1552
+ Specifies whether the calculation is done with the lower triangular
1553
+ part of `a` ('L', default) or the upper triangular part ('U').
1554
+ Irrespective of this value only the real parts of the diagonal will
1555
+ be considered in the computation to preserve the notion of a Hermitian
1556
+ matrix. It therefore follows that the imaginary part of the diagonal
1557
+ will always be treated as zero.
1558
+
1559
+ Returns
1560
+ -------
1561
+ A namedtuple with the following attributes:
1562
+
1563
+ eigenvalues : (..., M) ndarray
1564
+ The eigenvalues in ascending order, each repeated according to
1565
+ its multiplicity.
1566
+ eigenvectors : {(..., M, M) ndarray, (..., M, M) matrix}
1567
+ The column ``eigenvectors[:, i]`` is the normalized eigenvector
1568
+ corresponding to the eigenvalue ``eigenvalues[i]``. Will return a
1569
+ matrix object if `a` is a matrix object.
1570
+
1571
+ Raises
1572
+ ------
1573
+ LinAlgError
1574
+ If the eigenvalue computation does not converge.
1575
+
1576
+ See Also
1577
+ --------
1578
+ eigvalsh : eigenvalues of real symmetric or complex Hermitian
1579
+ (conjugate symmetric) arrays.
1580
+ eig : eigenvalues and right eigenvectors for non-symmetric arrays.
1581
+ eigvals : eigenvalues of non-symmetric arrays.
1582
+ scipy.linalg.eigh : Similar function in SciPy (but also solves the
1583
+ generalized eigenvalue problem).
1584
+
1585
+ Notes
1586
+ -----
1587
+ Broadcasting rules apply, see the `numpy.linalg` documentation for
1588
+ details.
1589
+
1590
+ The eigenvalues/eigenvectors are computed using LAPACK routines ``_syevd``,
1591
+ ``_heevd``.
1592
+
1593
+ The eigenvalues of real symmetric or complex Hermitian matrices are always
1594
+ real. [1]_ The array `eigenvalues` of (column) eigenvectors is unitary and
1595
+ `a`, `eigenvalues`, and `eigenvectors` satisfy the equations ``dot(a,
1596
+ eigenvectors[:, i]) = eigenvalues[i] * eigenvectors[:, i]``.
1597
+
1598
+ References
1599
+ ----------
1600
+ .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
1601
+ FL, Academic Press, Inc., 1980, pg. 222.
1602
+
1603
+ Examples
1604
+ --------
1605
+ >>> import numpy as np
1606
+ >>> from numpy import linalg as LA
1607
+ >>> a = np.array([[1, -2j], [2j, 5]])
1608
+ >>> a
1609
+ array([[ 1.+0.j, -0.-2.j],
1610
+ [ 0.+2.j, 5.+0.j]])
1611
+ >>> eigenvalues, eigenvectors = LA.eigh(a)
1612
+ >>> eigenvalues
1613
+ array([0.17157288, 5.82842712])
1614
+ >>> eigenvectors
1615
+ array([[-0.92387953+0.j , -0.38268343+0.j ], # may vary
1616
+ [ 0. +0.38268343j, 0. -0.92387953j]])
1617
+
1618
+ >>> (np.dot(a, eigenvectors[:, 0]) -
1619
+ ... eigenvalues[0] * eigenvectors[:, 0]) # verify 1st eigenval/vec pair
1620
+ array([5.55111512e-17+0.0000000e+00j, 0.00000000e+00+1.2490009e-16j])
1621
+ >>> (np.dot(a, eigenvectors[:, 1]) -
1622
+ ... eigenvalues[1] * eigenvectors[:, 1]) # verify 2nd eigenval/vec pair
1623
+ array([0.+0.j, 0.+0.j])
1624
+
1625
+ >>> A = np.matrix(a) # what happens if input is a matrix object
1626
+ >>> A
1627
+ matrix([[ 1.+0.j, -0.-2.j],
1628
+ [ 0.+2.j, 5.+0.j]])
1629
+ >>> eigenvalues, eigenvectors = LA.eigh(A)
1630
+ >>> eigenvalues
1631
+ array([0.17157288, 5.82842712])
1632
+ >>> eigenvectors
1633
+ matrix([[-0.92387953+0.j , -0.38268343+0.j ], # may vary
1634
+ [ 0. +0.38268343j, 0. -0.92387953j]])
1635
+
1636
+ >>> # demonstrate the treatment of the imaginary part of the diagonal
1637
+ >>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]])
1638
+ >>> a
1639
+ array([[5.+2.j, 9.-2.j],
1640
+ [0.+2.j, 2.-1.j]])
1641
+ >>> # with UPLO='L' this is numerically equivalent to using LA.eig() with:
1642
+ >>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]])
1643
+ >>> b
1644
+ array([[5.+0.j, 0.-2.j],
1645
+ [0.+2.j, 2.+0.j]])
1646
+ >>> wa, va = LA.eigh(a)
1647
+ >>> wb, vb = LA.eig(b)
1648
+ >>> wa
1649
+ array([1., 6.])
1650
+ >>> wb
1651
+ array([6.+0.j, 1.+0.j])
1652
+ >>> va
1653
+ array([[-0.4472136 +0.j , -0.89442719+0.j ], # may vary
1654
+ [ 0. +0.89442719j, 0. -0.4472136j ]])
1655
+ >>> vb
1656
+ array([[ 0.89442719+0.j , -0. +0.4472136j],
1657
+ [-0. +0.4472136j, 0.89442719+0.j ]])
1658
+
1659
+ """
1660
+ UPLO = UPLO.upper()
1661
+ if UPLO not in ('L', 'U'):
1662
+ raise ValueError("UPLO argument must be 'L' or 'U'")
1663
+
1664
+ a, wrap = _makearray(a)
1665
+ _assert_stacked_square(a)
1666
+ t, result_t = _commonType(a)
1667
+
1668
+ if UPLO == 'L':
1669
+ gufunc = _umath_linalg.eigh_lo
1670
+ else:
1671
+ gufunc = _umath_linalg.eigh_up
1672
+
1673
+ signature = 'D->dD' if isComplexType(t) else 'd->dd'
1674
+ with errstate(call=_raise_linalgerror_eigenvalues_nonconvergence,
1675
+ invalid='call', over='ignore', divide='ignore',
1676
+ under='ignore'):
1677
+ w, vt = gufunc(a, signature=signature)
1678
+ w = w.astype(_realType(result_t), copy=False)
1679
+ vt = vt.astype(result_t, copy=False)
1680
+ return EighResult(w, wrap(vt))
1681
+
1682
+
1683
+ # Singular value decomposition
1684
+
1685
+ def _svd_dispatcher(a, full_matrices=None, compute_uv=None, hermitian=None):
1686
+ return (a,)
1687
+
1688
+
1689
+ @array_function_dispatch(_svd_dispatcher)
1690
+ def svd(a, full_matrices=True, compute_uv=True, hermitian=False):
1691
+ """
1692
+ Singular Value Decomposition.
1693
+
1694
+ When `a` is a 2D array, and ``full_matrices=False``, then it is
1695
+ factorized as ``u @ np.diag(s) @ vh = (u * s) @ vh``, where
1696
+ `u` and the Hermitian transpose of `vh` are 2D arrays with
1697
+ orthonormal columns and `s` is a 1D array of `a`'s singular
1698
+ values. When `a` is higher-dimensional, SVD is applied in
1699
+ stacked mode as explained below.
1700
+
1701
+ Parameters
1702
+ ----------
1703
+ a : (..., M, N) array_like
1704
+ A real or complex array with ``a.ndim >= 2``.
1705
+ full_matrices : bool, optional
1706
+ If True (default), `u` and `vh` have the shapes ``(..., M, M)`` and
1707
+ ``(..., N, N)``, respectively. Otherwise, the shapes are
1708
+ ``(..., M, K)`` and ``(..., K, N)``, respectively, where
1709
+ ``K = min(M, N)``.
1710
+ compute_uv : bool, optional
1711
+ Whether or not to compute `u` and `vh` in addition to `s`. True
1712
+ by default.
1713
+ hermitian : bool, optional
1714
+ If True, `a` is assumed to be Hermitian (symmetric if real-valued),
1715
+ enabling a more efficient method for finding singular values.
1716
+ Defaults to False.
1717
+
1718
+ Returns
1719
+ -------
1720
+ When `compute_uv` is True, the result is a namedtuple with the following
1721
+ attribute names:
1722
+
1723
+ U : { (..., M, M), (..., M, K) } array
1724
+ Unitary array(s). The first ``a.ndim - 2`` dimensions have the same
1725
+ size as those of the input `a`. The size of the last two dimensions
1726
+ depends on the value of `full_matrices`. Only returned when
1727
+ `compute_uv` is True.
1728
+ S : (..., K) array
1729
+ Vector(s) with the singular values, within each vector sorted in
1730
+ descending order. The first ``a.ndim - 2`` dimensions have the same
1731
+ size as those of the input `a`.
1732
+ Vh : { (..., N, N), (..., K, N) } array
1733
+ Unitary array(s). The first ``a.ndim - 2`` dimensions have the same
1734
+ size as those of the input `a`. The size of the last two dimensions
1735
+ depends on the value of `full_matrices`. Only returned when
1736
+ `compute_uv` is True.
1737
+
1738
+ Raises
1739
+ ------
1740
+ LinAlgError
1741
+ If SVD computation does not converge.
1742
+
1743
+ See Also
1744
+ --------
1745
+ scipy.linalg.svd : Similar function in SciPy.
1746
+ scipy.linalg.svdvals : Compute singular values of a matrix.
1747
+
1748
+ Notes
1749
+ -----
1750
+ The decomposition is performed using LAPACK routine ``_gesdd``.
1751
+
1752
+ SVD is usually described for the factorization of a 2D matrix :math:`A`.
1753
+ The higher-dimensional case will be discussed below. In the 2D case, SVD is
1754
+ written as :math:`A = U S V^H`, where :math:`A = a`, :math:`U= u`,
1755
+ :math:`S= \\mathtt{np.diag}(s)` and :math:`V^H = vh`. The 1D array `s`
1756
+ contains the singular values of `a` and `u` and `vh` are unitary. The rows
1757
+ of `vh` are the eigenvectors of :math:`A^H A` and the columns of `u` are
1758
+ the eigenvectors of :math:`A A^H`. In both cases the corresponding
1759
+ (possibly non-zero) eigenvalues are given by ``s**2``.
1760
+
1761
+ If `a` has more than two dimensions, then broadcasting rules apply, as
1762
+ explained in :ref:`routines.linalg-broadcasting`. This means that SVD is
1763
+ working in "stacked" mode: it iterates over all indices of the first
1764
+ ``a.ndim - 2`` dimensions and for each combination SVD is applied to the
1765
+ last two indices. The matrix `a` can be reconstructed from the
1766
+ decomposition with either ``(u * s[..., None, :]) @ vh`` or
1767
+ ``u @ (s[..., None] * vh)``. (The ``@`` operator can be replaced by the
1768
+ function ``np.matmul`` for python versions below 3.5.)
1769
+
1770
+ If `a` is a ``matrix`` object (as opposed to an ``ndarray``), then so are
1771
+ all the return values.
1772
+
1773
+ Examples
1774
+ --------
1775
+ >>> import numpy as np
1776
+ >>> rng = np.random.default_rng()
1777
+ >>> a = rng.normal(size=(9, 6)) + 1j*rng.normal(size=(9, 6))
1778
+ >>> b = rng.normal(size=(2, 7, 8, 3)) + 1j*rng.normal(size=(2, 7, 8, 3))
1779
+
1780
+
1781
+ Reconstruction based on full SVD, 2D case:
1782
+
1783
+ >>> U, S, Vh = np.linalg.svd(a, full_matrices=True)
1784
+ >>> U.shape, S.shape, Vh.shape
1785
+ ((9, 9), (6,), (6, 6))
1786
+ >>> np.allclose(a, np.dot(U[:, :6] * S, Vh))
1787
+ True
1788
+ >>> smat = np.zeros((9, 6), dtype=complex)
1789
+ >>> smat[:6, :6] = np.diag(S)
1790
+ >>> np.allclose(a, np.dot(U, np.dot(smat, Vh)))
1791
+ True
1792
+
1793
+ Reconstruction based on reduced SVD, 2D case:
1794
+
1795
+ >>> U, S, Vh = np.linalg.svd(a, full_matrices=False)
1796
+ >>> U.shape, S.shape, Vh.shape
1797
+ ((9, 6), (6,), (6, 6))
1798
+ >>> np.allclose(a, np.dot(U * S, Vh))
1799
+ True
1800
+ >>> smat = np.diag(S)
1801
+ >>> np.allclose(a, np.dot(U, np.dot(smat, Vh)))
1802
+ True
1803
+
1804
+ Reconstruction based on full SVD, 4D case:
1805
+
1806
+ >>> U, S, Vh = np.linalg.svd(b, full_matrices=True)
1807
+ >>> U.shape, S.shape, Vh.shape
1808
+ ((2, 7, 8, 8), (2, 7, 3), (2, 7, 3, 3))
1809
+ >>> np.allclose(b, np.matmul(U[..., :3] * S[..., None, :], Vh))
1810
+ True
1811
+ >>> np.allclose(b, np.matmul(U[..., :3], S[..., None] * Vh))
1812
+ True
1813
+
1814
+ Reconstruction based on reduced SVD, 4D case:
1815
+
1816
+ >>> U, S, Vh = np.linalg.svd(b, full_matrices=False)
1817
+ >>> U.shape, S.shape, Vh.shape
1818
+ ((2, 7, 8, 3), (2, 7, 3), (2, 7, 3, 3))
1819
+ >>> np.allclose(b, np.matmul(U * S[..., None, :], Vh))
1820
+ True
1821
+ >>> np.allclose(b, np.matmul(U, S[..., None] * Vh))
1822
+ True
1823
+
1824
+ """
1825
+ import numpy as np
1826
+ a, wrap = _makearray(a)
1827
+
1828
+ if hermitian:
1829
+ # note: lapack svd returns eigenvalues with s ** 2 sorted descending,
1830
+ # but eig returns s sorted ascending, so we re-order the eigenvalues
1831
+ # and related arrays to have the correct order
1832
+ if compute_uv:
1833
+ s, u = eigh(a)
1834
+ sgn = sign(s)
1835
+ s = abs(s)
1836
+ sidx = argsort(s)[..., ::-1]
1837
+ sgn = np.take_along_axis(sgn, sidx, axis=-1)
1838
+ s = np.take_along_axis(s, sidx, axis=-1)
1839
+ u = np.take_along_axis(u, sidx[..., None, :], axis=-1)
1840
+ # singular values are unsigned, move the sign into v
1841
+ vt = transpose(u * sgn[..., None, :]).conjugate()
1842
+ return SVDResult(wrap(u), s, wrap(vt))
1843
+ else:
1844
+ s = eigvalsh(a)
1845
+ s = abs(s)
1846
+ return sort(s)[..., ::-1]
1847
+
1848
+ _assert_stacked_2d(a)
1849
+ t, result_t = _commonType(a)
1850
+
1851
+ m, n = a.shape[-2:]
1852
+ if compute_uv:
1853
+ if full_matrices:
1854
+ gufunc = _umath_linalg.svd_f
1855
+ else:
1856
+ gufunc = _umath_linalg.svd_s
1857
+
1858
+ signature = 'D->DdD' if isComplexType(t) else 'd->ddd'
1859
+ with errstate(call=_raise_linalgerror_svd_nonconvergence,
1860
+ invalid='call', over='ignore', divide='ignore',
1861
+ under='ignore'):
1862
+ u, s, vh = gufunc(a, signature=signature)
1863
+ u = u.astype(result_t, copy=False)
1864
+ s = s.astype(_realType(result_t), copy=False)
1865
+ vh = vh.astype(result_t, copy=False)
1866
+ return SVDResult(wrap(u), s, wrap(vh))
1867
+ else:
1868
+ signature = 'D->d' if isComplexType(t) else 'd->d'
1869
+ with errstate(call=_raise_linalgerror_svd_nonconvergence,
1870
+ invalid='call', over='ignore', divide='ignore',
1871
+ under='ignore'):
1872
+ s = _umath_linalg.svd(a, signature=signature)
1873
+ s = s.astype(_realType(result_t), copy=False)
1874
+ return s
1875
+
1876
+
1877
+ def _svdvals_dispatcher(x):
1878
+ return (x,)
1879
+
1880
+
1881
+ @array_function_dispatch(_svdvals_dispatcher)
1882
+ def svdvals(x, /):
1883
+ """
1884
+ Returns the singular values of a matrix (or a stack of matrices) ``x``.
1885
+ When x is a stack of matrices, the function will compute the singular
1886
+ values for each matrix in the stack.
1887
+
1888
+ This function is Array API compatible.
1889
+
1890
+ Calling ``np.svdvals(x)`` to get singular values is the same as
1891
+ ``np.svd(x, compute_uv=False, hermitian=False)``.
1892
+
1893
+ Parameters
1894
+ ----------
1895
+ x : (..., M, N) array_like
1896
+ Input array having shape (..., M, N) and whose last two
1897
+ dimensions form matrices on which to perform singular value
1898
+ decomposition. Should have a floating-point data type.
1899
+
1900
+ Returns
1901
+ -------
1902
+ out : ndarray
1903
+ An array with shape (..., K) that contains the vector(s)
1904
+ of singular values of length K, where K = min(M, N).
1905
+
1906
+ See Also
1907
+ --------
1908
+ scipy.linalg.svdvals : Compute singular values of a matrix.
1909
+
1910
+ Examples
1911
+ --------
1912
+
1913
+ >>> np.linalg.svdvals([[1, 2, 3, 4, 5],
1914
+ ... [1, 4, 9, 16, 25],
1915
+ ... [1, 8, 27, 64, 125]])
1916
+ array([146.68862757, 5.57510612, 0.60393245])
1917
+
1918
+ Determine the rank of a matrix using singular values:
1919
+
1920
+ >>> s = np.linalg.svdvals([[1, 2, 3],
1921
+ ... [2, 4, 6],
1922
+ ... [-1, 1, -1]]); s
1923
+ array([8.38434191e+00, 1.64402274e+00, 2.31534378e-16])
1924
+ >>> np.count_nonzero(s > 1e-10) # Matrix of rank 2
1925
+ 2
1926
+
1927
+ """
1928
+ return svd(x, compute_uv=False, hermitian=False)
1929
+
1930
+
1931
+ def _cond_dispatcher(x, p=None):
1932
+ return (x,)
1933
+
1934
+
1935
+ @array_function_dispatch(_cond_dispatcher)
1936
+ def cond(x, p=None):
1937
+ """
1938
+ Compute the condition number of a matrix.
1939
+
1940
+ This function is capable of returning the condition number using
1941
+ one of seven different norms, depending on the value of `p` (see
1942
+ Parameters below).
1943
+
1944
+ Parameters
1945
+ ----------
1946
+ x : (..., M, N) array_like
1947
+ The matrix whose condition number is sought.
1948
+ p : {None, 1, -1, 2, -2, inf, -inf, 'fro'}, optional
1949
+ Order of the norm used in the condition number computation:
1950
+
1951
+ ===== ============================
1952
+ p norm for matrices
1953
+ ===== ============================
1954
+ None 2-norm, computed directly using the ``SVD``
1955
+ 'fro' Frobenius norm
1956
+ inf max(sum(abs(x), axis=1))
1957
+ -inf min(sum(abs(x), axis=1))
1958
+ 1 max(sum(abs(x), axis=0))
1959
+ -1 min(sum(abs(x), axis=0))
1960
+ 2 2-norm (largest sing. value)
1961
+ -2 smallest singular value
1962
+ ===== ============================
1963
+
1964
+ inf means the `numpy.inf` object, and the Frobenius norm is
1965
+ the root-of-sum-of-squares norm.
1966
+
1967
+ Returns
1968
+ -------
1969
+ c : {float, inf}
1970
+ The condition number of the matrix. May be infinite.
1971
+
1972
+ See Also
1973
+ --------
1974
+ numpy.linalg.norm
1975
+
1976
+ Notes
1977
+ -----
1978
+ The condition number of `x` is defined as the norm of `x` times the
1979
+ norm of the inverse of `x` [1]_; the norm can be the usual L2-norm
1980
+ (root-of-sum-of-squares) or one of a number of other matrix norms.
1981
+
1982
+ References
1983
+ ----------
1984
+ .. [1] G. Strang, *Linear Algebra and Its Applications*, Orlando, FL,
1985
+ Academic Press, Inc., 1980, pg. 285.
1986
+
1987
+ Examples
1988
+ --------
1989
+ >>> import numpy as np
1990
+ >>> from numpy import linalg as LA
1991
+ >>> a = np.array([[1, 0, -1], [0, 1, 0], [1, 0, 1]])
1992
+ >>> a
1993
+ array([[ 1, 0, -1],
1994
+ [ 0, 1, 0],
1995
+ [ 1, 0, 1]])
1996
+ >>> LA.cond(a)
1997
+ 1.4142135623730951
1998
+ >>> LA.cond(a, 'fro')
1999
+ 3.1622776601683795
2000
+ >>> LA.cond(a, np.inf)
2001
+ 2.0
2002
+ >>> LA.cond(a, -np.inf)
2003
+ 1.0
2004
+ >>> LA.cond(a, 1)
2005
+ 2.0
2006
+ >>> LA.cond(a, -1)
2007
+ 1.0
2008
+ >>> LA.cond(a, 2)
2009
+ 1.4142135623730951
2010
+ >>> LA.cond(a, -2)
2011
+ 0.70710678118654746 # may vary
2012
+ >>> (min(LA.svd(a, compute_uv=False)) *
2013
+ ... min(LA.svd(LA.inv(a), compute_uv=False)))
2014
+ 0.70710678118654746 # may vary
2015
+
2016
+ """
2017
+ x = asarray(x) # in case we have a matrix
2018
+ if _is_empty_2d(x):
2019
+ raise LinAlgError("cond is not defined on empty arrays")
2020
+ if p is None or p in {2, -2}:
2021
+ s = svd(x, compute_uv=False)
2022
+ with errstate(all='ignore'):
2023
+ if p == -2:
2024
+ r = s[..., -1] / s[..., 0]
2025
+ else:
2026
+ r = s[..., 0] / s[..., -1]
2027
+ else:
2028
+ # Call inv(x) ignoring errors. The result array will
2029
+ # contain nans in the entries where inversion failed.
2030
+ _assert_stacked_square(x)
2031
+ t, result_t = _commonType(x)
2032
+ result_t = _realType(result_t) # condition number is always real
2033
+ signature = 'D->D' if isComplexType(t) else 'd->d'
2034
+ with errstate(all='ignore'):
2035
+ invx = _umath_linalg.inv(x, signature=signature)
2036
+ r = norm(x, p, axis=(-2, -1)) * norm(invx, p, axis=(-2, -1))
2037
+ r = r.astype(result_t, copy=False)
2038
+
2039
+ # Convert nans to infs unless the original array had nan entries
2040
+ r = asarray(r)
2041
+ nan_mask = isnan(r)
2042
+ if nan_mask.any():
2043
+ nan_mask &= ~isnan(x).any(axis=(-2, -1))
2044
+ if r.ndim > 0:
2045
+ r[nan_mask] = inf
2046
+ elif nan_mask:
2047
+ r[()] = inf
2048
+
2049
+ # Convention is to return scalars instead of 0d arrays
2050
+ if r.ndim == 0:
2051
+ r = r[()]
2052
+
2053
+ return r
2054
+
2055
+
2056
+ def _matrix_rank_dispatcher(A, tol=None, hermitian=None, *, rtol=None):
2057
+ return (A,)
2058
+
2059
+
2060
+ @array_function_dispatch(_matrix_rank_dispatcher)
2061
+ def matrix_rank(A, tol=None, hermitian=False, *, rtol=None):
2062
+ """
2063
+ Return matrix rank of array using SVD method
2064
+
2065
+ Rank of the array is the number of singular values of the array that are
2066
+ greater than `tol`.
2067
+
2068
+ Parameters
2069
+ ----------
2070
+ A : {(M,), (..., M, N)} array_like
2071
+ Input vector or stack of matrices.
2072
+ tol : (...) array_like, float, optional
2073
+ Threshold below which SVD values are considered zero. If `tol` is
2074
+ None, and ``S`` is an array with singular values for `M`, and
2075
+ ``eps`` is the epsilon value for datatype of ``S``, then `tol` is
2076
+ set to ``S.max() * max(M, N) * eps``.
2077
+ hermitian : bool, optional
2078
+ If True, `A` is assumed to be Hermitian (symmetric if real-valued),
2079
+ enabling a more efficient method for finding singular values.
2080
+ Defaults to False.
2081
+ rtol : (...) array_like, float, optional
2082
+ Parameter for the relative tolerance component. Only ``tol`` or
2083
+ ``rtol`` can be set at a time. Defaults to ``max(M, N) * eps``.
2084
+
2085
+ .. versionadded:: 2.0.0
2086
+
2087
+ Returns
2088
+ -------
2089
+ rank : (...) array_like
2090
+ Rank of A.
2091
+
2092
+ Notes
2093
+ -----
2094
+ The default threshold to detect rank deficiency is a test on the magnitude
2095
+ of the singular values of `A`. By default, we identify singular values
2096
+ less than ``S.max() * max(M, N) * eps`` as indicating rank deficiency
2097
+ (with the symbols defined above). This is the algorithm MATLAB uses [1].
2098
+ It also appears in *Numerical recipes* in the discussion of SVD solutions
2099
+ for linear least squares [2].
2100
+
2101
+ This default threshold is designed to detect rank deficiency accounting
2102
+ for the numerical errors of the SVD computation. Imagine that there
2103
+ is a column in `A` that is an exact (in floating point) linear combination
2104
+ of other columns in `A`. Computing the SVD on `A` will not produce
2105
+ a singular value exactly equal to 0 in general: any difference of
2106
+ the smallest SVD value from 0 will be caused by numerical imprecision
2107
+ in the calculation of the SVD. Our threshold for small SVD values takes
2108
+ this numerical imprecision into account, and the default threshold will
2109
+ detect such numerical rank deficiency. The threshold may declare a matrix
2110
+ `A` rank deficient even if the linear combination of some columns of `A`
2111
+ is not exactly equal to another column of `A` but only numerically very
2112
+ close to another column of `A`.
2113
+
2114
+ We chose our default threshold because it is in wide use. Other thresholds
2115
+ are possible. For example, elsewhere in the 2007 edition of *Numerical
2116
+ recipes* there is an alternative threshold of ``S.max() *
2117
+ np.finfo(A.dtype).eps / 2. * np.sqrt(m + n + 1.)``. The authors describe
2118
+ this threshold as being based on "expected roundoff error" (p 71).
2119
+
2120
+ The thresholds above deal with floating point roundoff error in the
2121
+ calculation of the SVD. However, you may have more information about
2122
+ the sources of error in `A` that would make you consider other tolerance
2123
+ values to detect *effective* rank deficiency. The most useful measure
2124
+ of the tolerance depends on the operations you intend to use on your
2125
+ matrix. For example, if your data come from uncertain measurements with
2126
+ uncertainties greater than floating point epsilon, choosing a tolerance
2127
+ near that uncertainty may be preferable. The tolerance may be absolute
2128
+ if the uncertainties are absolute rather than relative.
2129
+
2130
+ References
2131
+ ----------
2132
+ .. [1] MATLAB reference documentation, "Rank"
2133
+ https://www.mathworks.com/help/techdoc/ref/rank.html
2134
+ .. [2] W. H. Press, S. A. Teukolsky, W. T. Vetterling and B. P. Flannery,
2135
+ "Numerical Recipes (3rd edition)", Cambridge University Press, 2007,
2136
+ page 795.
2137
+
2138
+ Examples
2139
+ --------
2140
+ >>> import numpy as np
2141
+ >>> from numpy.linalg import matrix_rank
2142
+ >>> matrix_rank(np.eye(4)) # Full rank matrix
2143
+ 4
2144
+ >>> I=np.eye(4); I[-1,-1] = 0. # rank deficient matrix
2145
+ >>> matrix_rank(I)
2146
+ 3
2147
+ >>> matrix_rank(np.ones((4,))) # 1 dimension - rank 1 unless all 0
2148
+ 1
2149
+ >>> matrix_rank(np.zeros((4,)))
2150
+ 0
2151
+ """
2152
+ if rtol is not None and tol is not None:
2153
+ raise ValueError("`tol` and `rtol` can't be both set.")
2154
+
2155
+ A = asarray(A)
2156
+ if A.ndim < 2:
2157
+ return int(not all(A == 0))
2158
+ S = svd(A, compute_uv=False, hermitian=hermitian)
2159
+
2160
+ if tol is None:
2161
+ if rtol is None:
2162
+ rtol = max(A.shape[-2:]) * finfo(S.dtype).eps
2163
+ else:
2164
+ rtol = asarray(rtol)[..., newaxis]
2165
+ tol = S.max(axis=-1, keepdims=True) * rtol
2166
+ else:
2167
+ tol = asarray(tol)[..., newaxis]
2168
+
2169
+ return count_nonzero(S > tol, axis=-1)
2170
+
2171
+
2172
+ # Generalized inverse
2173
+
2174
+ def _pinv_dispatcher(a, rcond=None, hermitian=None, *, rtol=None):
2175
+ return (a,)
2176
+
2177
+
2178
+ @array_function_dispatch(_pinv_dispatcher)
2179
+ def pinv(a, rcond=None, hermitian=False, *, rtol=_NoValue):
2180
+ """
2181
+ Compute the (Moore-Penrose) pseudo-inverse of a matrix.
2182
+
2183
+ Calculate the generalized inverse of a matrix using its
2184
+ singular-value decomposition (SVD) and including all
2185
+ *large* singular values.
2186
+
2187
+ Parameters
2188
+ ----------
2189
+ a : (..., M, N) array_like
2190
+ Matrix or stack of matrices to be pseudo-inverted.
2191
+ rcond : (...) array_like of float, optional
2192
+ Cutoff for small singular values.
2193
+ Singular values less than or equal to
2194
+ ``rcond * largest_singular_value`` are set to zero.
2195
+ Broadcasts against the stack of matrices. Default: ``1e-15``.
2196
+ hermitian : bool, optional
2197
+ If True, `a` is assumed to be Hermitian (symmetric if real-valued),
2198
+ enabling a more efficient method for finding singular values.
2199
+ Defaults to False.
2200
+ rtol : (...) array_like of float, optional
2201
+ Same as `rcond`, but it's an Array API compatible parameter name.
2202
+ Only `rcond` or `rtol` can be set at a time. If none of them are
2203
+ provided then NumPy's ``1e-15`` default is used. If ``rtol=None``
2204
+ is passed then the API standard default is used.
2205
+
2206
+ .. versionadded:: 2.0.0
2207
+
2208
+ Returns
2209
+ -------
2210
+ B : (..., N, M) ndarray
2211
+ The pseudo-inverse of `a`. If `a` is a `matrix` instance, then so
2212
+ is `B`.
2213
+
2214
+ Raises
2215
+ ------
2216
+ LinAlgError
2217
+ If the SVD computation does not converge.
2218
+
2219
+ See Also
2220
+ --------
2221
+ scipy.linalg.pinv : Similar function in SciPy.
2222
+ scipy.linalg.pinvh : Compute the (Moore-Penrose) pseudo-inverse of a
2223
+ Hermitian matrix.
2224
+
2225
+ Notes
2226
+ -----
2227
+ The pseudo-inverse of a matrix A, denoted :math:`A^+`, is
2228
+ defined as: "the matrix that 'solves' [the least-squares problem]
2229
+ :math:`Ax = b`," i.e., if :math:`\\bar{x}` is said solution, then
2230
+ :math:`A^+` is that matrix such that :math:`\\bar{x} = A^+b`.
2231
+
2232
+ It can be shown that if :math:`Q_1 \\Sigma Q_2^T = A` is the singular
2233
+ value decomposition of A, then
2234
+ :math:`A^+ = Q_2 \\Sigma^+ Q_1^T`, where :math:`Q_{1,2}` are
2235
+ orthogonal matrices, :math:`\\Sigma` is a diagonal matrix consisting
2236
+ of A's so-called singular values, (followed, typically, by
2237
+ zeros), and then :math:`\\Sigma^+` is simply the diagonal matrix
2238
+ consisting of the reciprocals of A's singular values
2239
+ (again, followed by zeros). [1]_
2240
+
2241
+ References
2242
+ ----------
2243
+ .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
2244
+ FL, Academic Press, Inc., 1980, pp. 139-142.
2245
+
2246
+ Examples
2247
+ --------
2248
+ The following example checks that ``a * a+ * a == a`` and
2249
+ ``a+ * a * a+ == a+``:
2250
+
2251
+ >>> import numpy as np
2252
+ >>> rng = np.random.default_rng()
2253
+ >>> a = rng.normal(size=(9, 6))
2254
+ >>> B = np.linalg.pinv(a)
2255
+ >>> np.allclose(a, np.dot(a, np.dot(B, a)))
2256
+ True
2257
+ >>> np.allclose(B, np.dot(B, np.dot(a, B)))
2258
+ True
2259
+
2260
+ """
2261
+ a, wrap = _makearray(a)
2262
+ if rcond is None:
2263
+ if rtol is _NoValue:
2264
+ rcond = 1e-15
2265
+ elif rtol is None:
2266
+ rcond = max(a.shape[-2:]) * finfo(a.dtype).eps
2267
+ else:
2268
+ rcond = rtol
2269
+ elif rtol is not _NoValue:
2270
+ raise ValueError("`rtol` and `rcond` can't be both set.")
2271
+ else:
2272
+ # NOTE: Deprecate `rcond` in a few versions.
2273
+ pass
2274
+
2275
+ rcond = asarray(rcond)
2276
+ if _is_empty_2d(a):
2277
+ m, n = a.shape[-2:]
2278
+ res = empty(a.shape[:-2] + (n, m), dtype=a.dtype)
2279
+ return wrap(res)
2280
+ a = a.conjugate()
2281
+ u, s, vt = svd(a, full_matrices=False, hermitian=hermitian)
2282
+
2283
+ # discard small singular values
2284
+ cutoff = rcond[..., newaxis] * amax(s, axis=-1, keepdims=True)
2285
+ large = s > cutoff
2286
+ s = divide(1, s, where=large, out=s)
2287
+ s[~large] = 0
2288
+
2289
+ res = matmul(transpose(vt), multiply(s[..., newaxis], transpose(u)))
2290
+ return wrap(res)
2291
+
2292
+
2293
+ # Determinant
2294
+
2295
+
2296
+ @array_function_dispatch(_unary_dispatcher)
2297
+ def slogdet(a):
2298
+ """
2299
+ Compute the sign and (natural) logarithm of the determinant of an array.
2300
+
2301
+ If an array has a very small or very large determinant, then a call to
2302
+ `det` may overflow or underflow. This routine is more robust against such
2303
+ issues, because it computes the logarithm of the determinant rather than
2304
+ the determinant itself.
2305
+
2306
+ Parameters
2307
+ ----------
2308
+ a : (..., M, M) array_like
2309
+ Input array, has to be a square 2-D array.
2310
+
2311
+ Returns
2312
+ -------
2313
+ A namedtuple with the following attributes:
2314
+
2315
+ sign : (...) array_like
2316
+ A number representing the sign of the determinant. For a real matrix,
2317
+ this is 1, 0, or -1. For a complex matrix, this is a complex number
2318
+ with absolute value 1 (i.e., it is on the unit circle), or else 0.
2319
+ logabsdet : (...) array_like
2320
+ The natural log of the absolute value of the determinant.
2321
+
2322
+ If the determinant is zero, then `sign` will be 0 and `logabsdet`
2323
+ will be -inf. In all cases, the determinant is equal to
2324
+ ``sign * np.exp(logabsdet)``.
2325
+
2326
+ See Also
2327
+ --------
2328
+ det
2329
+
2330
+ Notes
2331
+ -----
2332
+ Broadcasting rules apply, see the `numpy.linalg` documentation for
2333
+ details.
2334
+
2335
+ The determinant is computed via LU factorization using the LAPACK
2336
+ routine ``z/dgetrf``.
2337
+
2338
+ Examples
2339
+ --------
2340
+ The determinant of a 2-D array ``[[a, b], [c, d]]`` is ``ad - bc``:
2341
+
2342
+ >>> import numpy as np
2343
+ >>> a = np.array([[1, 2], [3, 4]])
2344
+ >>> (sign, logabsdet) = np.linalg.slogdet(a)
2345
+ >>> (sign, logabsdet)
2346
+ (-1, 0.69314718055994529) # may vary
2347
+ >>> sign * np.exp(logabsdet)
2348
+ -2.0
2349
+
2350
+ Computing log-determinants for a stack of matrices:
2351
+
2352
+ >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ])
2353
+ >>> a.shape
2354
+ (3, 2, 2)
2355
+ >>> sign, logabsdet = np.linalg.slogdet(a)
2356
+ >>> (sign, logabsdet)
2357
+ (array([-1., -1., -1.]), array([ 0.69314718, 1.09861229, 2.07944154]))
2358
+ >>> sign * np.exp(logabsdet)
2359
+ array([-2., -3., -8.])
2360
+
2361
+ This routine succeeds where ordinary `det` does not:
2362
+
2363
+ >>> np.linalg.det(np.eye(500) * 0.1)
2364
+ 0.0
2365
+ >>> np.linalg.slogdet(np.eye(500) * 0.1)
2366
+ (1, -1151.2925464970228)
2367
+
2368
+ """
2369
+ a = asarray(a)
2370
+ _assert_stacked_square(a)
2371
+ t, result_t = _commonType(a)
2372
+ real_t = _realType(result_t)
2373
+ signature = 'D->Dd' if isComplexType(t) else 'd->dd'
2374
+ sign, logdet = _umath_linalg.slogdet(a, signature=signature)
2375
+ sign = sign.astype(result_t, copy=False)
2376
+ logdet = logdet.astype(real_t, copy=False)
2377
+ return SlogdetResult(sign, logdet)
2378
+
2379
+
2380
+ @array_function_dispatch(_unary_dispatcher)
2381
+ def det(a):
2382
+ """
2383
+ Compute the determinant of an array.
2384
+
2385
+ Parameters
2386
+ ----------
2387
+ a : (..., M, M) array_like
2388
+ Input array to compute determinants for.
2389
+
2390
+ Returns
2391
+ -------
2392
+ det : (...) array_like
2393
+ Determinant of `a`.
2394
+
2395
+ See Also
2396
+ --------
2397
+ slogdet : Another way to represent the determinant, more suitable
2398
+ for large matrices where underflow/overflow may occur.
2399
+ scipy.linalg.det : Similar function in SciPy.
2400
+
2401
+ Notes
2402
+ -----
2403
+ Broadcasting rules apply, see the `numpy.linalg` documentation for
2404
+ details.
2405
+
2406
+ The determinant is computed via LU factorization using the LAPACK
2407
+ routine ``z/dgetrf``.
2408
+
2409
+ Examples
2410
+ --------
2411
+ The determinant of a 2-D array [[a, b], [c, d]] is ad - bc:
2412
+
2413
+ >>> import numpy as np
2414
+ >>> a = np.array([[1, 2], [3, 4]])
2415
+ >>> np.linalg.det(a)
2416
+ -2.0 # may vary
2417
+
2418
+ Computing determinants for a stack of matrices:
2419
+
2420
+ >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ])
2421
+ >>> a.shape
2422
+ (3, 2, 2)
2423
+ >>> np.linalg.det(a)
2424
+ array([-2., -3., -8.])
2425
+
2426
+ """
2427
+ a = asarray(a)
2428
+ _assert_stacked_square(a)
2429
+ t, result_t = _commonType(a)
2430
+ signature = 'D->D' if isComplexType(t) else 'd->d'
2431
+ r = _umath_linalg.det(a, signature=signature)
2432
+ r = r.astype(result_t, copy=False)
2433
+ return r
2434
+
2435
+
2436
+ # Linear Least Squares
2437
+
2438
+ def _lstsq_dispatcher(a, b, rcond=None):
2439
+ return (a, b)
2440
+
2441
+
2442
+ @array_function_dispatch(_lstsq_dispatcher)
2443
+ def lstsq(a, b, rcond=None):
2444
+ r"""
2445
+ Return the least-squares solution to a linear matrix equation.
2446
+
2447
+ Computes the vector `x` that approximately solves the equation
2448
+ ``a @ x = b``. The equation may be under-, well-, or over-determined
2449
+ (i.e., the number of linearly independent rows of `a` can be less than,
2450
+ equal to, or greater than its number of linearly independent columns).
2451
+ If `a` is square and of full rank, then `x` (but for round-off error)
2452
+ is the "exact" solution of the equation. Else, `x` minimizes the
2453
+ Euclidean 2-norm :math:`||b - ax||`. If there are multiple minimizing
2454
+ solutions, the one with the smallest 2-norm :math:`||x||` is returned.
2455
+
2456
+ Parameters
2457
+ ----------
2458
+ a : (M, N) array_like
2459
+ "Coefficient" matrix.
2460
+ b : {(M,), (M, K)} array_like
2461
+ Ordinate or "dependent variable" values. If `b` is two-dimensional,
2462
+ the least-squares solution is calculated for each of the `K` columns
2463
+ of `b`.
2464
+ rcond : float, optional
2465
+ Cut-off ratio for small singular values of `a`.
2466
+ For the purposes of rank determination, singular values are treated
2467
+ as zero if they are smaller than `rcond` times the largest singular
2468
+ value of `a`.
2469
+ The default uses the machine precision times ``max(M, N)``. Passing
2470
+ ``-1`` will use machine precision.
2471
+
2472
+ .. versionchanged:: 2.0
2473
+ Previously, the default was ``-1``, but a warning was given that
2474
+ this would change.
2475
+
2476
+ Returns
2477
+ -------
2478
+ x : {(N,), (N, K)} ndarray
2479
+ Least-squares solution. If `b` is two-dimensional,
2480
+ the solutions are in the `K` columns of `x`.
2481
+ residuals : {(1,), (K,), (0,)} ndarray
2482
+ Sums of squared residuals: Squared Euclidean 2-norm for each column in
2483
+ ``b - a @ x``.
2484
+ If the rank of `a` is < N or M <= N, this is an empty array.
2485
+ If `b` is 1-dimensional, this is a (1,) shape array.
2486
+ Otherwise the shape is (K,).
2487
+ rank : int
2488
+ Rank of matrix `a`.
2489
+ s : (min(M, N),) ndarray
2490
+ Singular values of `a`.
2491
+
2492
+ Raises
2493
+ ------
2494
+ LinAlgError
2495
+ If computation does not converge.
2496
+
2497
+ See Also
2498
+ --------
2499
+ scipy.linalg.lstsq : Similar function in SciPy.
2500
+
2501
+ Notes
2502
+ -----
2503
+ If `b` is a matrix, then all array results are returned as matrices.
2504
+
2505
+ Examples
2506
+ --------
2507
+ Fit a line, ``y = mx + c``, through some noisy data-points:
2508
+
2509
+ >>> import numpy as np
2510
+ >>> x = np.array([0, 1, 2, 3])
2511
+ >>> y = np.array([-1, 0.2, 0.9, 2.1])
2512
+
2513
+ By examining the coefficients, we see that the line should have a
2514
+ gradient of roughly 1 and cut the y-axis at, more or less, -1.
2515
+
2516
+ We can rewrite the line equation as ``y = Ap``, where ``A = [[x 1]]``
2517
+ and ``p = [[m], [c]]``. Now use `lstsq` to solve for `p`:
2518
+
2519
+ >>> A = np.vstack([x, np.ones(len(x))]).T
2520
+ >>> A
2521
+ array([[ 0., 1.],
2522
+ [ 1., 1.],
2523
+ [ 2., 1.],
2524
+ [ 3., 1.]])
2525
+
2526
+ >>> m, c = np.linalg.lstsq(A, y)[0]
2527
+ >>> m, c
2528
+ (1.0 -0.95) # may vary
2529
+
2530
+ Plot the data along with the fitted line:
2531
+
2532
+ >>> import matplotlib.pyplot as plt
2533
+ >>> _ = plt.plot(x, y, 'o', label='Original data', markersize=10)
2534
+ >>> _ = plt.plot(x, m*x + c, 'r', label='Fitted line')
2535
+ >>> _ = plt.legend()
2536
+ >>> plt.show()
2537
+
2538
+ """
2539
+ a, _ = _makearray(a)
2540
+ b, wrap = _makearray(b)
2541
+ is_1d = b.ndim == 1
2542
+ if is_1d:
2543
+ b = b[:, newaxis]
2544
+ _assert_2d(a, b)
2545
+ m, n = a.shape[-2:]
2546
+ m2, n_rhs = b.shape[-2:]
2547
+ if m != m2:
2548
+ raise LinAlgError('Incompatible dimensions')
2549
+
2550
+ t, result_t = _commonType(a, b)
2551
+ result_real_t = _realType(result_t)
2552
+
2553
+ if rcond is None:
2554
+ rcond = finfo(t).eps * max(n, m)
2555
+
2556
+ signature = 'DDd->Ddid' if isComplexType(t) else 'ddd->ddid'
2557
+ if n_rhs == 0:
2558
+ # lapack can't handle n_rhs = 0 - so allocate
2559
+ # the array one larger in that axis
2560
+ b = zeros(b.shape[:-2] + (m, n_rhs + 1), dtype=b.dtype)
2561
+
2562
+ with errstate(call=_raise_linalgerror_lstsq, invalid='call',
2563
+ over='ignore', divide='ignore', under='ignore'):
2564
+ x, resids, rank, s = _umath_linalg.lstsq(a, b, rcond,
2565
+ signature=signature)
2566
+ if m == 0:
2567
+ x[...] = 0
2568
+ if n_rhs == 0:
2569
+ # remove the item we added
2570
+ x = x[..., :n_rhs]
2571
+ resids = resids[..., :n_rhs]
2572
+
2573
+ # remove the axis we added
2574
+ if is_1d:
2575
+ x = x.squeeze(axis=-1)
2576
+ # we probably should squeeze resids too, but we can't
2577
+ # without breaking compatibility.
2578
+
2579
+ # as documented
2580
+ if rank != n or m <= n:
2581
+ resids = array([], result_real_t)
2582
+
2583
+ # coerce output arrays
2584
+ s = s.astype(result_real_t, copy=False)
2585
+ resids = resids.astype(result_real_t, copy=False)
2586
+ # Copying lets the memory in r_parts be freed
2587
+ x = x.astype(result_t, copy=True)
2588
+ return wrap(x), wrap(resids), rank, s
2589
+
2590
+
2591
+ def _multi_svd_norm(x, row_axis, col_axis, op, initial=None):
2592
+ """Compute a function of the singular values of the 2-D matrices in `x`.
2593
+
2594
+ This is a private utility function used by `numpy.linalg.norm()`.
2595
+
2596
+ Parameters
2597
+ ----------
2598
+ x : ndarray
2599
+ row_axis, col_axis : int
2600
+ The axes of `x` that hold the 2-D matrices.
2601
+ op : callable
2602
+ This should be either numpy.amin or `numpy.amax` or `numpy.sum`.
2603
+
2604
+ Returns
2605
+ -------
2606
+ result : float or ndarray
2607
+ If `x` is 2-D, the return values is a float.
2608
+ Otherwise, it is an array with ``x.ndim - 2`` dimensions.
2609
+ The return values are either the minimum or maximum or sum of the
2610
+ singular values of the matrices, depending on whether `op`
2611
+ is `numpy.amin` or `numpy.amax` or `numpy.sum`.
2612
+
2613
+ """
2614
+ y = moveaxis(x, (row_axis, col_axis), (-2, -1))
2615
+ result = op(svd(y, compute_uv=False), axis=-1, initial=initial)
2616
+ return result
2617
+
2618
+
2619
+ def _norm_dispatcher(x, ord=None, axis=None, keepdims=None):
2620
+ return (x,)
2621
+
2622
+
2623
+ @array_function_dispatch(_norm_dispatcher)
2624
+ def norm(x, ord=None, axis=None, keepdims=False):
2625
+ """
2626
+ Matrix or vector norm.
2627
+
2628
+ This function is able to return one of eight different matrix norms,
2629
+ or one of an infinite number of vector norms (described below), depending
2630
+ on the value of the ``ord`` parameter.
2631
+
2632
+ Parameters
2633
+ ----------
2634
+ x : array_like
2635
+ Input array. If `axis` is None, `x` must be 1-D or 2-D, unless `ord`
2636
+ is None. If both `axis` and `ord` are None, the 2-norm of
2637
+ ``x.ravel`` will be returned.
2638
+ ord : {int, float, inf, -inf, 'fro', 'nuc'}, optional
2639
+ Order of the norm (see table under ``Notes`` for what values are
2640
+ supported for matrices and vectors respectively). inf means numpy's
2641
+ `inf` object. The default is None.
2642
+ axis : {None, int, 2-tuple of ints}, optional.
2643
+ If `axis` is an integer, it specifies the axis of `x` along which to
2644
+ compute the vector norms. If `axis` is a 2-tuple, it specifies the
2645
+ axes that hold 2-D matrices, and the matrix norms of these matrices
2646
+ are computed. If `axis` is None then either a vector norm (when `x`
2647
+ is 1-D) or a matrix norm (when `x` is 2-D) is returned. The default
2648
+ is None.
2649
+
2650
+ keepdims : bool, optional
2651
+ If this is set to True, the axes which are normed over are left in the
2652
+ result as dimensions with size one. With this option the result will
2653
+ broadcast correctly against the original `x`.
2654
+
2655
+ Returns
2656
+ -------
2657
+ n : float or ndarray
2658
+ Norm of the matrix or vector(s).
2659
+
2660
+ See Also
2661
+ --------
2662
+ scipy.linalg.norm : Similar function in SciPy.
2663
+
2664
+ Notes
2665
+ -----
2666
+ For values of ``ord < 1``, the result is, strictly speaking, not a
2667
+ mathematical 'norm', but it may still be useful for various numerical
2668
+ purposes.
2669
+
2670
+ The following norms can be calculated:
2671
+
2672
+ ===== ============================ ==========================
2673
+ ord norm for matrices norm for vectors
2674
+ ===== ============================ ==========================
2675
+ None Frobenius norm 2-norm
2676
+ 'fro' Frobenius norm --
2677
+ 'nuc' nuclear norm --
2678
+ inf max(sum(abs(x), axis=1)) max(abs(x))
2679
+ -inf min(sum(abs(x), axis=1)) min(abs(x))
2680
+ 0 -- sum(x != 0)
2681
+ 1 max(sum(abs(x), axis=0)) as below
2682
+ -1 min(sum(abs(x), axis=0)) as below
2683
+ 2 2-norm (largest sing. value) as below
2684
+ -2 smallest singular value as below
2685
+ other -- sum(abs(x)**ord)**(1./ord)
2686
+ ===== ============================ ==========================
2687
+
2688
+ The Frobenius norm is given by [1]_:
2689
+
2690
+ :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}`
2691
+
2692
+ The nuclear norm is the sum of the singular values.
2693
+
2694
+ Both the Frobenius and nuclear norm orders are only defined for
2695
+ matrices and raise a ValueError when ``x.ndim != 2``.
2696
+
2697
+ References
2698
+ ----------
2699
+ .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*,
2700
+ Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15
2701
+
2702
+ Examples
2703
+ --------
2704
+
2705
+ >>> import numpy as np
2706
+ >>> from numpy import linalg as LA
2707
+ >>> a = np.arange(9) - 4
2708
+ >>> a
2709
+ array([-4, -3, -2, ..., 2, 3, 4])
2710
+ >>> b = a.reshape((3, 3))
2711
+ >>> b
2712
+ array([[-4, -3, -2],
2713
+ [-1, 0, 1],
2714
+ [ 2, 3, 4]])
2715
+
2716
+ >>> LA.norm(a)
2717
+ 7.745966692414834
2718
+ >>> LA.norm(b)
2719
+ 7.745966692414834
2720
+ >>> LA.norm(b, 'fro')
2721
+ 7.745966692414834
2722
+ >>> LA.norm(a, np.inf)
2723
+ 4.0
2724
+ >>> LA.norm(b, np.inf)
2725
+ 9.0
2726
+ >>> LA.norm(a, -np.inf)
2727
+ 0.0
2728
+ >>> LA.norm(b, -np.inf)
2729
+ 2.0
2730
+
2731
+ >>> LA.norm(a, 1)
2732
+ 20.0
2733
+ >>> LA.norm(b, 1)
2734
+ 7.0
2735
+ >>> LA.norm(a, -1)
2736
+ -4.6566128774142013e-010
2737
+ >>> LA.norm(b, -1)
2738
+ 6.0
2739
+ >>> LA.norm(a, 2)
2740
+ 7.745966692414834
2741
+ >>> LA.norm(b, 2)
2742
+ 7.3484692283495345
2743
+
2744
+ >>> LA.norm(a, -2)
2745
+ 0.0
2746
+ >>> LA.norm(b, -2)
2747
+ 1.8570331885190563e-016 # may vary
2748
+ >>> LA.norm(a, 3)
2749
+ 5.8480354764257312 # may vary
2750
+ >>> LA.norm(a, -3)
2751
+ 0.0
2752
+
2753
+ Using the `axis` argument to compute vector norms:
2754
+
2755
+ >>> c = np.array([[ 1, 2, 3],
2756
+ ... [-1, 1, 4]])
2757
+ >>> LA.norm(c, axis=0)
2758
+ array([ 1.41421356, 2.23606798, 5. ])
2759
+ >>> LA.norm(c, axis=1)
2760
+ array([ 3.74165739, 4.24264069])
2761
+ >>> LA.norm(c, ord=1, axis=1)
2762
+ array([ 6., 6.])
2763
+
2764
+ Using the `axis` argument to compute matrix norms:
2765
+
2766
+ >>> m = np.arange(8).reshape(2,2,2)
2767
+ >>> LA.norm(m, axis=(1,2))
2768
+ array([ 3.74165739, 11.22497216])
2769
+ >>> LA.norm(m[0, :, :]), LA.norm(m[1, :, :])
2770
+ (3.7416573867739413, 11.224972160321824)
2771
+
2772
+ """
2773
+ x = asarray(x)
2774
+
2775
+ if not issubclass(x.dtype.type, (inexact, object_)):
2776
+ x = x.astype(float)
2777
+
2778
+ # Immediately handle some default, simple, fast, and common cases.
2779
+ if axis is None:
2780
+ ndim = x.ndim
2781
+ if (
2782
+ (ord is None) or
2783
+ (ord in ('f', 'fro') and ndim == 2) or
2784
+ (ord == 2 and ndim == 1)
2785
+ ):
2786
+ x = x.ravel(order='K')
2787
+ if isComplexType(x.dtype.type):
2788
+ x_real = x.real
2789
+ x_imag = x.imag
2790
+ sqnorm = x_real.dot(x_real) + x_imag.dot(x_imag)
2791
+ else:
2792
+ sqnorm = x.dot(x)
2793
+ ret = sqrt(sqnorm)
2794
+ if keepdims:
2795
+ ret = ret.reshape(ndim * [1])
2796
+ return ret
2797
+
2798
+ # Normalize the `axis` argument to a tuple.
2799
+ nd = x.ndim
2800
+ if axis is None:
2801
+ axis = tuple(range(nd))
2802
+ elif not isinstance(axis, tuple):
2803
+ try:
2804
+ axis = int(axis)
2805
+ except Exception as e:
2806
+ raise TypeError(
2807
+ "'axis' must be None, an integer or a tuple of integers"
2808
+ ) from e
2809
+ axis = (axis,)
2810
+
2811
+ if len(axis) == 1:
2812
+ if ord == inf:
2813
+ return abs(x).max(axis=axis, keepdims=keepdims, initial=0)
2814
+ elif ord == -inf:
2815
+ return abs(x).min(axis=axis, keepdims=keepdims)
2816
+ elif ord == 0:
2817
+ # Zero norm
2818
+ return (
2819
+ (x != 0)
2820
+ .astype(x.real.dtype)
2821
+ .sum(axis=axis, keepdims=keepdims)
2822
+ )
2823
+ elif ord == 1:
2824
+ # special case for speedup
2825
+ return add.reduce(abs(x), axis=axis, keepdims=keepdims)
2826
+ elif ord is None or ord == 2:
2827
+ # special case for speedup
2828
+ s = (x.conj() * x).real
2829
+ return sqrt(add.reduce(s, axis=axis, keepdims=keepdims))
2830
+ # None of the str-type keywords for ord ('fro', 'nuc')
2831
+ # are valid for vectors
2832
+ elif isinstance(ord, str):
2833
+ raise ValueError(f"Invalid norm order '{ord}' for vectors")
2834
+ else:
2835
+ absx = abs(x)
2836
+ absx **= ord
2837
+ ret = add.reduce(absx, axis=axis, keepdims=keepdims)
2838
+ ret **= reciprocal(ord, dtype=ret.dtype)
2839
+ return ret
2840
+ elif len(axis) == 2:
2841
+ row_axis, col_axis = axis
2842
+ row_axis = normalize_axis_index(row_axis, nd)
2843
+ col_axis = normalize_axis_index(col_axis, nd)
2844
+ if row_axis == col_axis:
2845
+ raise ValueError('Duplicate axes given.')
2846
+ if ord == 2:
2847
+ ret = _multi_svd_norm(x, row_axis, col_axis, amax, 0)
2848
+ elif ord == -2:
2849
+ ret = _multi_svd_norm(x, row_axis, col_axis, amin)
2850
+ elif ord == 1:
2851
+ if col_axis > row_axis:
2852
+ col_axis -= 1
2853
+ ret = add.reduce(abs(x), axis=row_axis).max(axis=col_axis, initial=0)
2854
+ elif ord == inf:
2855
+ if row_axis > col_axis:
2856
+ row_axis -= 1
2857
+ ret = add.reduce(abs(x), axis=col_axis).max(axis=row_axis, initial=0)
2858
+ elif ord == -1:
2859
+ if col_axis > row_axis:
2860
+ col_axis -= 1
2861
+ ret = add.reduce(abs(x), axis=row_axis).min(axis=col_axis)
2862
+ elif ord == -inf:
2863
+ if row_axis > col_axis:
2864
+ row_axis -= 1
2865
+ ret = add.reduce(abs(x), axis=col_axis).min(axis=row_axis)
2866
+ elif ord in [None, 'fro', 'f']:
2867
+ ret = sqrt(add.reduce((x.conj() * x).real, axis=axis))
2868
+ elif ord == 'nuc':
2869
+ ret = _multi_svd_norm(x, row_axis, col_axis, sum, 0)
2870
+ else:
2871
+ raise ValueError("Invalid norm order for matrices.")
2872
+ if keepdims:
2873
+ ret_shape = list(x.shape)
2874
+ ret_shape[axis[0]] = 1
2875
+ ret_shape[axis[1]] = 1
2876
+ ret = ret.reshape(ret_shape)
2877
+ return ret
2878
+ else:
2879
+ raise ValueError("Improper number of dimensions to norm.")
2880
+
2881
+
2882
+ # multi_dot
2883
+
2884
+ def _multidot_dispatcher(arrays, *, out=None):
2885
+ yield from arrays
2886
+ yield out
2887
+
2888
+
2889
+ @array_function_dispatch(_multidot_dispatcher)
2890
+ def multi_dot(arrays, *, out=None):
2891
+ """
2892
+ Compute the dot product of two or more arrays in a single function call,
2893
+ while automatically selecting the fastest evaluation order.
2894
+
2895
+ `multi_dot` chains `numpy.dot` and uses optimal parenthesization
2896
+ of the matrices [1]_ [2]_. Depending on the shapes of the matrices,
2897
+ this can speed up the multiplication a lot.
2898
+
2899
+ If the first argument is 1-D it is treated as a row vector.
2900
+ If the last argument is 1-D it is treated as a column vector.
2901
+ The other arguments must be 2-D.
2902
+
2903
+ Think of `multi_dot` as::
2904
+
2905
+ def multi_dot(arrays): return functools.reduce(np.dot, arrays)
2906
+
2907
+
2908
+ Parameters
2909
+ ----------
2910
+ arrays : sequence of array_like
2911
+ If the first argument is 1-D it is treated as row vector.
2912
+ If the last argument is 1-D it is treated as column vector.
2913
+ The other arguments must be 2-D.
2914
+ out : ndarray, optional
2915
+ Output argument. This must have the exact kind that would be returned
2916
+ if it was not used. In particular, it must have the right type, must be
2917
+ C-contiguous, and its dtype must be the dtype that would be returned
2918
+ for `dot(a, b)`. This is a performance feature. Therefore, if these
2919
+ conditions are not met, an exception is raised, instead of attempting
2920
+ to be flexible.
2921
+
2922
+ Returns
2923
+ -------
2924
+ output : ndarray
2925
+ Returns the dot product of the supplied arrays.
2926
+
2927
+ See Also
2928
+ --------
2929
+ numpy.dot : dot multiplication with two arguments.
2930
+
2931
+ References
2932
+ ----------
2933
+
2934
+ .. [1] Cormen, "Introduction to Algorithms", Chapter 15.2, p. 370-378
2935
+ .. [2] https://en.wikipedia.org/wiki/Matrix_chain_multiplication
2936
+
2937
+ Examples
2938
+ --------
2939
+ `multi_dot` allows you to write::
2940
+
2941
+ >>> import numpy as np
2942
+ >>> from numpy.linalg import multi_dot
2943
+ >>> # Prepare some data
2944
+ >>> A = np.random.random((10000, 100))
2945
+ >>> B = np.random.random((100, 1000))
2946
+ >>> C = np.random.random((1000, 5))
2947
+ >>> D = np.random.random((5, 333))
2948
+ >>> # the actual dot multiplication
2949
+ >>> _ = multi_dot([A, B, C, D])
2950
+
2951
+ instead of::
2952
+
2953
+ >>> _ = np.dot(np.dot(np.dot(A, B), C), D)
2954
+ >>> # or
2955
+ >>> _ = A.dot(B).dot(C).dot(D)
2956
+
2957
+ Notes
2958
+ -----
2959
+ The cost for a matrix multiplication can be calculated with the
2960
+ following function::
2961
+
2962
+ def cost(A, B):
2963
+ return A.shape[0] * A.shape[1] * B.shape[1]
2964
+
2965
+ Assume we have three matrices
2966
+ :math:`A_{10 \times 100}, B_{100 \times 5}, C_{5 \times 50}`.
2967
+
2968
+ The costs for the two different parenthesizations are as follows::
2969
+
2970
+ cost((AB)C) = 10*100*5 + 10*5*50 = 5000 + 2500 = 7500
2971
+ cost(A(BC)) = 10*100*50 + 100*5*50 = 50000 + 25000 = 75000
2972
+
2973
+ """
2974
+ n = len(arrays)
2975
+ # optimization only makes sense for len(arrays) > 2
2976
+ if n < 2:
2977
+ raise ValueError("Expecting at least two arrays.")
2978
+ elif n == 2:
2979
+ return dot(arrays[0], arrays[1], out=out)
2980
+
2981
+ arrays = [asanyarray(a) for a in arrays]
2982
+
2983
+ # save original ndim to reshape the result array into the proper form later
2984
+ ndim_first, ndim_last = arrays[0].ndim, arrays[-1].ndim
2985
+ # Explicitly convert vectors to 2D arrays to keep the logic of the internal
2986
+ # _multi_dot_* functions as simple as possible.
2987
+ if arrays[0].ndim == 1:
2988
+ arrays[0] = atleast_2d(arrays[0])
2989
+ if arrays[-1].ndim == 1:
2990
+ arrays[-1] = atleast_2d(arrays[-1]).T
2991
+ _assert_2d(*arrays)
2992
+
2993
+ # _multi_dot_three is much faster than _multi_dot_matrix_chain_order
2994
+ if n == 3:
2995
+ result = _multi_dot_three(arrays[0], arrays[1], arrays[2], out=out)
2996
+ else:
2997
+ order = _multi_dot_matrix_chain_order(arrays)
2998
+ result = _multi_dot(arrays, order, 0, n - 1, out=out)
2999
+
3000
+ # return proper shape
3001
+ if ndim_first == 1 and ndim_last == 1:
3002
+ return result[0, 0] # scalar
3003
+ elif ndim_first == 1 or ndim_last == 1:
3004
+ return result.ravel() # 1-D
3005
+ else:
3006
+ return result
3007
+
3008
+
3009
+ def _multi_dot_three(A, B, C, out=None):
3010
+ """
3011
+ Find the best order for three arrays and do the multiplication.
3012
+
3013
+ For three arguments `_multi_dot_three` is approximately 15 times faster
3014
+ than `_multi_dot_matrix_chain_order`
3015
+
3016
+ """
3017
+ a0, a1b0 = A.shape
3018
+ b1c0, c1 = C.shape
3019
+ # cost1 = cost((AB)C) = a0*a1b0*b1c0 + a0*b1c0*c1
3020
+ cost1 = a0 * b1c0 * (a1b0 + c1)
3021
+ # cost2 = cost(A(BC)) = a1b0*b1c0*c1 + a0*a1b0*c1
3022
+ cost2 = a1b0 * c1 * (a0 + b1c0)
3023
+
3024
+ if cost1 < cost2:
3025
+ return dot(dot(A, B), C, out=out)
3026
+ else:
3027
+ return dot(A, dot(B, C), out=out)
3028
+
3029
+
3030
+ def _multi_dot_matrix_chain_order(arrays, return_costs=False):
3031
+ """
3032
+ Return a np.array that encodes the optimal order of multiplications.
3033
+
3034
+ The optimal order array is then used by `_multi_dot()` to do the
3035
+ multiplication.
3036
+
3037
+ Also return the cost matrix if `return_costs` is `True`
3038
+
3039
+ The implementation CLOSELY follows Cormen, "Introduction to Algorithms",
3040
+ Chapter 15.2, p. 370-378. Note that Cormen uses 1-based indices.
3041
+
3042
+ cost[i, j] = min([
3043
+ cost[prefix] + cost[suffix] + cost_mult(prefix, suffix)
3044
+ for k in range(i, j)])
3045
+
3046
+ """
3047
+ n = len(arrays)
3048
+ # p stores the dimensions of the matrices
3049
+ # Example for p: A_{10x100}, B_{100x5}, C_{5x50} --> p = [10, 100, 5, 50]
3050
+ p = [a.shape[0] for a in arrays] + [arrays[-1].shape[1]]
3051
+ # m is a matrix of costs of the subproblems
3052
+ # m[i,j]: min number of scalar multiplications needed to compute A_{i..j}
3053
+ m = zeros((n, n), dtype=double)
3054
+ # s is the actual ordering
3055
+ # s[i, j] is the value of k at which we split the product A_i..A_j
3056
+ s = empty((n, n), dtype=intp)
3057
+
3058
+ for l in range(1, n):
3059
+ for i in range(n - l):
3060
+ j = i + l
3061
+ m[i, j] = inf
3062
+ for k in range(i, j):
3063
+ q = m[i, k] + m[k + 1, j] + p[i] * p[k + 1] * p[j + 1]
3064
+ if q < m[i, j]:
3065
+ m[i, j] = q
3066
+ s[i, j] = k # Note that Cormen uses 1-based index
3067
+
3068
+ return (s, m) if return_costs else s
3069
+
3070
+
3071
+ def _multi_dot(arrays, order, i, j, out=None):
3072
+ """Actually do the multiplication with the given order."""
3073
+ if i == j:
3074
+ # the initial call with non-None out should never get here
3075
+ assert out is None
3076
+
3077
+ return arrays[i]
3078
+ else:
3079
+ return dot(_multi_dot(arrays, order, i, order[i, j]),
3080
+ _multi_dot(arrays, order, order[i, j] + 1, j),
3081
+ out=out)
3082
+
3083
+
3084
+ # diagonal
3085
+
3086
+ def _diagonal_dispatcher(x, /, *, offset=None):
3087
+ return (x,)
3088
+
3089
+
3090
+ @array_function_dispatch(_diagonal_dispatcher)
3091
+ def diagonal(x, /, *, offset=0):
3092
+ """
3093
+ Returns specified diagonals of a matrix (or a stack of matrices) ``x``.
3094
+
3095
+ This function is Array API compatible, contrary to
3096
+ :py:func:`numpy.diagonal`, the matrix is assumed
3097
+ to be defined by the last two dimensions.
3098
+
3099
+ Parameters
3100
+ ----------
3101
+ x : (...,M,N) array_like
3102
+ Input array having shape (..., M, N) and whose innermost two
3103
+ dimensions form MxN matrices.
3104
+ offset : int, optional
3105
+ Offset specifying the off-diagonal relative to the main diagonal,
3106
+ where::
3107
+
3108
+ * offset = 0: the main diagonal.
3109
+ * offset > 0: off-diagonal above the main diagonal.
3110
+ * offset < 0: off-diagonal below the main diagonal.
3111
+
3112
+ Returns
3113
+ -------
3114
+ out : (...,min(N,M)) ndarray
3115
+ An array containing the diagonals and whose shape is determined by
3116
+ removing the last two dimensions and appending a dimension equal to
3117
+ the size of the resulting diagonals. The returned array must have
3118
+ the same data type as ``x``.
3119
+
3120
+ See Also
3121
+ --------
3122
+ numpy.diagonal
3123
+
3124
+ Examples
3125
+ --------
3126
+ >>> a = np.arange(4).reshape(2, 2); a
3127
+ array([[0, 1],
3128
+ [2, 3]])
3129
+ >>> np.linalg.diagonal(a)
3130
+ array([0, 3])
3131
+
3132
+ A 3-D example:
3133
+
3134
+ >>> a = np.arange(8).reshape(2, 2, 2); a
3135
+ array([[[0, 1],
3136
+ [2, 3]],
3137
+ [[4, 5],
3138
+ [6, 7]]])
3139
+ >>> np.linalg.diagonal(a)
3140
+ array([[0, 3],
3141
+ [4, 7]])
3142
+
3143
+ Diagonals adjacent to the main diagonal can be obtained by using the
3144
+ `offset` argument:
3145
+
3146
+ >>> a = np.arange(9).reshape(3, 3)
3147
+ >>> a
3148
+ array([[0, 1, 2],
3149
+ [3, 4, 5],
3150
+ [6, 7, 8]])
3151
+ >>> np.linalg.diagonal(a, offset=1) # First superdiagonal
3152
+ array([1, 5])
3153
+ >>> np.linalg.diagonal(a, offset=2) # Second superdiagonal
3154
+ array([2])
3155
+ >>> np.linalg.diagonal(a, offset=-1) # First subdiagonal
3156
+ array([3, 7])
3157
+ >>> np.linalg.diagonal(a, offset=-2) # Second subdiagonal
3158
+ array([6])
3159
+
3160
+ The anti-diagonal can be obtained by reversing the order of elements
3161
+ using either `numpy.flipud` or `numpy.fliplr`.
3162
+
3163
+ >>> a = np.arange(9).reshape(3, 3)
3164
+ >>> a
3165
+ array([[0, 1, 2],
3166
+ [3, 4, 5],
3167
+ [6, 7, 8]])
3168
+ >>> np.linalg.diagonal(np.fliplr(a)) # Horizontal flip
3169
+ array([2, 4, 6])
3170
+ >>> np.linalg.diagonal(np.flipud(a)) # Vertical flip
3171
+ array([6, 4, 2])
3172
+
3173
+ Note that the order in which the diagonal is retrieved varies depending
3174
+ on the flip function.
3175
+
3176
+ """
3177
+ return _core_diagonal(x, offset, axis1=-2, axis2=-1)
3178
+
3179
+
3180
+ # trace
3181
+
3182
+ def _trace_dispatcher(x, /, *, offset=None, dtype=None):
3183
+ return (x,)
3184
+
3185
+
3186
+ @array_function_dispatch(_trace_dispatcher)
3187
+ def trace(x, /, *, offset=0, dtype=None):
3188
+ """
3189
+ Returns the sum along the specified diagonals of a matrix
3190
+ (or a stack of matrices) ``x``.
3191
+
3192
+ This function is Array API compatible, contrary to
3193
+ :py:func:`numpy.trace`.
3194
+
3195
+ Parameters
3196
+ ----------
3197
+ x : (...,M,N) array_like
3198
+ Input array having shape (..., M, N) and whose innermost two
3199
+ dimensions form MxN matrices.
3200
+ offset : int, optional
3201
+ Offset specifying the off-diagonal relative to the main diagonal,
3202
+ where::
3203
+
3204
+ * offset = 0: the main diagonal.
3205
+ * offset > 0: off-diagonal above the main diagonal.
3206
+ * offset < 0: off-diagonal below the main diagonal.
3207
+
3208
+ dtype : dtype, optional
3209
+ Data type of the returned array.
3210
+
3211
+ Returns
3212
+ -------
3213
+ out : ndarray
3214
+ An array containing the traces and whose shape is determined by
3215
+ removing the last two dimensions and storing the traces in the last
3216
+ array dimension. For example, if x has rank k and shape:
3217
+ (I, J, K, ..., L, M, N), then an output array has rank k-2 and shape:
3218
+ (I, J, K, ..., L) where::
3219
+
3220
+ out[i, j, k, ..., l] = trace(a[i, j, k, ..., l, :, :])
3221
+
3222
+ The returned array must have a data type as described by the dtype
3223
+ parameter above.
3224
+
3225
+ See Also
3226
+ --------
3227
+ numpy.trace
3228
+
3229
+ Examples
3230
+ --------
3231
+ >>> np.linalg.trace(np.eye(3))
3232
+ 3.0
3233
+ >>> a = np.arange(8).reshape((2, 2, 2))
3234
+ >>> np.linalg.trace(a)
3235
+ array([3, 11])
3236
+
3237
+ Trace is computed with the last two axes as the 2-d sub-arrays.
3238
+ This behavior differs from :py:func:`numpy.trace` which uses the first two
3239
+ axes by default.
3240
+
3241
+ >>> a = np.arange(24).reshape((3, 2, 2, 2))
3242
+ >>> np.linalg.trace(a).shape
3243
+ (3, 2)
3244
+
3245
+ Traces adjacent to the main diagonal can be obtained by using the
3246
+ `offset` argument:
3247
+
3248
+ >>> a = np.arange(9).reshape((3, 3)); a
3249
+ array([[0, 1, 2],
3250
+ [3, 4, 5],
3251
+ [6, 7, 8]])
3252
+ >>> np.linalg.trace(a, offset=1) # First superdiagonal
3253
+ 6
3254
+ >>> np.linalg.trace(a, offset=2) # Second superdiagonal
3255
+ 2
3256
+ >>> np.linalg.trace(a, offset=-1) # First subdiagonal
3257
+ 10
3258
+ >>> np.linalg.trace(a, offset=-2) # Second subdiagonal
3259
+ 6
3260
+
3261
+ """
3262
+ return _core_trace(x, offset, axis1=-2, axis2=-1, dtype=dtype)
3263
+
3264
+
3265
+ # cross
3266
+
3267
+ def _cross_dispatcher(x1, x2, /, *, axis=None):
3268
+ return (x1, x2,)
3269
+
3270
+
3271
+ @array_function_dispatch(_cross_dispatcher)
3272
+ def cross(x1, x2, /, *, axis=-1):
3273
+ """
3274
+ Returns the cross product of 3-element vectors.
3275
+
3276
+ If ``x1`` and/or ``x2`` are multi-dimensional arrays, then
3277
+ the cross-product of each pair of corresponding 3-element vectors
3278
+ is independently computed.
3279
+
3280
+ This function is Array API compatible, contrary to
3281
+ :func:`numpy.cross`.
3282
+
3283
+ Parameters
3284
+ ----------
3285
+ x1 : array_like
3286
+ The first input array.
3287
+ x2 : array_like
3288
+ The second input array. Must be compatible with ``x1`` for all
3289
+ non-compute axes. The size of the axis over which to compute
3290
+ the cross-product must be the same size as the respective axis
3291
+ in ``x1``.
3292
+ axis : int, optional
3293
+ The axis (dimension) of ``x1`` and ``x2`` containing the vectors for
3294
+ which to compute the cross-product. Default: ``-1``.
3295
+
3296
+ Returns
3297
+ -------
3298
+ out : ndarray
3299
+ An array containing the cross products.
3300
+
3301
+ See Also
3302
+ --------
3303
+ numpy.cross
3304
+
3305
+ Examples
3306
+ --------
3307
+ Vector cross-product.
3308
+
3309
+ >>> x = np.array([1, 2, 3])
3310
+ >>> y = np.array([4, 5, 6])
3311
+ >>> np.linalg.cross(x, y)
3312
+ array([-3, 6, -3])
3313
+
3314
+ Multiple vector cross-products. Note that the direction of the cross
3315
+ product vector is defined by the *right-hand rule*.
3316
+
3317
+ >>> x = np.array([[1,2,3], [4,5,6]])
3318
+ >>> y = np.array([[4,5,6], [1,2,3]])
3319
+ >>> np.linalg.cross(x, y)
3320
+ array([[-3, 6, -3],
3321
+ [ 3, -6, 3]])
3322
+
3323
+ >>> x = np.array([[1, 2], [3, 4], [5, 6]])
3324
+ >>> y = np.array([[4, 5], [6, 1], [2, 3]])
3325
+ >>> np.linalg.cross(x, y, axis=0)
3326
+ array([[-24, 6],
3327
+ [ 18, 24],
3328
+ [-6, -18]])
3329
+
3330
+ """
3331
+ x1 = asanyarray(x1)
3332
+ x2 = asanyarray(x2)
3333
+
3334
+ if x1.shape[axis] != 3 or x2.shape[axis] != 3:
3335
+ raise ValueError(
3336
+ "Both input arrays must be (arrays of) 3-dimensional vectors, "
3337
+ f"but they are {x1.shape[axis]} and {x2.shape[axis]} "
3338
+ "dimensional instead."
3339
+ )
3340
+
3341
+ return _core_cross(x1, x2, axis=axis)
3342
+
3343
+
3344
+ # matmul
3345
+
3346
+ def _matmul_dispatcher(x1, x2, /):
3347
+ return (x1, x2)
3348
+
3349
+
3350
+ @array_function_dispatch(_matmul_dispatcher)
3351
+ def matmul(x1, x2, /):
3352
+ """
3353
+ Computes the matrix product.
3354
+
3355
+ This function is Array API compatible, contrary to
3356
+ :func:`numpy.matmul`.
3357
+
3358
+ Parameters
3359
+ ----------
3360
+ x1 : array_like
3361
+ The first input array.
3362
+ x2 : array_like
3363
+ The second input array.
3364
+
3365
+ Returns
3366
+ -------
3367
+ out : ndarray
3368
+ The matrix product of the inputs.
3369
+ This is a scalar only when both ``x1``, ``x2`` are 1-d vectors.
3370
+
3371
+ Raises
3372
+ ------
3373
+ ValueError
3374
+ If the last dimension of ``x1`` is not the same size as
3375
+ the second-to-last dimension of ``x2``.
3376
+
3377
+ If a scalar value is passed in.
3378
+
3379
+ See Also
3380
+ --------
3381
+ numpy.matmul
3382
+
3383
+ Examples
3384
+ --------
3385
+ For 2-D arrays it is the matrix product:
3386
+
3387
+ >>> a = np.array([[1, 0],
3388
+ ... [0, 1]])
3389
+ >>> b = np.array([[4, 1],
3390
+ ... [2, 2]])
3391
+ >>> np.linalg.matmul(a, b)
3392
+ array([[4, 1],
3393
+ [2, 2]])
3394
+
3395
+ For 2-D mixed with 1-D, the result is the usual.
3396
+
3397
+ >>> a = np.array([[1, 0],
3398
+ ... [0, 1]])
3399
+ >>> b = np.array([1, 2])
3400
+ >>> np.linalg.matmul(a, b)
3401
+ array([1, 2])
3402
+ >>> np.linalg.matmul(b, a)
3403
+ array([1, 2])
3404
+
3405
+
3406
+ Broadcasting is conventional for stacks of arrays
3407
+
3408
+ >>> a = np.arange(2 * 2 * 4).reshape((2, 2, 4))
3409
+ >>> b = np.arange(2 * 2 * 4).reshape((2, 4, 2))
3410
+ >>> np.linalg.matmul(a,b).shape
3411
+ (2, 2, 2)
3412
+ >>> np.linalg.matmul(a, b)[0, 1, 1]
3413
+ 98
3414
+ >>> sum(a[0, 1, :] * b[0 , :, 1])
3415
+ 98
3416
+
3417
+ Vector, vector returns the scalar inner product, but neither argument
3418
+ is complex-conjugated:
3419
+
3420
+ >>> np.linalg.matmul([2j, 3j], [2j, 3j])
3421
+ (-13+0j)
3422
+
3423
+ Scalar multiplication raises an error.
3424
+
3425
+ >>> np.linalg.matmul([1,2], 3)
3426
+ Traceback (most recent call last):
3427
+ ...
3428
+ ValueError: matmul: Input operand 1 does not have enough dimensions ...
3429
+
3430
+ """
3431
+ return _core_matmul(x1, x2)
3432
+
3433
+
3434
+ # tensordot
3435
+
3436
+ def _tensordot_dispatcher(x1, x2, /, *, axes=None):
3437
+ return (x1, x2)
3438
+
3439
+
3440
+ @array_function_dispatch(_tensordot_dispatcher)
3441
+ def tensordot(x1, x2, /, *, axes=2):
3442
+ return _core_tensordot(x1, x2, axes=axes)
3443
+
3444
+
3445
+ tensordot.__doc__ = _core_tensordot.__doc__
3446
+
3447
+
3448
+ # matrix_transpose
3449
+
3450
+ def _matrix_transpose_dispatcher(x):
3451
+ return (x,)
3452
+
3453
+ @array_function_dispatch(_matrix_transpose_dispatcher)
3454
+ def matrix_transpose(x, /):
3455
+ return _core_matrix_transpose(x)
3456
+
3457
+
3458
+ matrix_transpose.__doc__ = f"""{_core_matrix_transpose.__doc__}
3459
+
3460
+ Notes
3461
+ -----
3462
+ This function is an alias of `numpy.matrix_transpose`.
3463
+ """
3464
+
3465
+
3466
+ # matrix_norm
3467
+
3468
+ def _matrix_norm_dispatcher(x, /, *, keepdims=None, ord=None):
3469
+ return (x,)
3470
+
3471
+ @array_function_dispatch(_matrix_norm_dispatcher)
3472
+ def matrix_norm(x, /, *, keepdims=False, ord="fro"):
3473
+ """
3474
+ Computes the matrix norm of a matrix (or a stack of matrices) ``x``.
3475
+
3476
+ This function is Array API compatible.
3477
+
3478
+ Parameters
3479
+ ----------
3480
+ x : array_like
3481
+ Input array having shape (..., M, N) and whose two innermost
3482
+ dimensions form ``MxN`` matrices.
3483
+ keepdims : bool, optional
3484
+ If this is set to True, the axes which are normed over are left in
3485
+ the result as dimensions with size one. Default: False.
3486
+ ord : {1, -1, 2, -2, inf, -inf, 'fro', 'nuc'}, optional
3487
+ The order of the norm. For details see the table under ``Notes``
3488
+ in `numpy.linalg.norm`.
3489
+
3490
+ See Also
3491
+ --------
3492
+ numpy.linalg.norm : Generic norm function
3493
+
3494
+ Examples
3495
+ --------
3496
+ >>> from numpy import linalg as LA
3497
+ >>> a = np.arange(9) - 4
3498
+ >>> a
3499
+ array([-4, -3, -2, ..., 2, 3, 4])
3500
+ >>> b = a.reshape((3, 3))
3501
+ >>> b
3502
+ array([[-4, -3, -2],
3503
+ [-1, 0, 1],
3504
+ [ 2, 3, 4]])
3505
+
3506
+ >>> LA.matrix_norm(b)
3507
+ 7.745966692414834
3508
+ >>> LA.matrix_norm(b, ord='fro')
3509
+ 7.745966692414834
3510
+ >>> LA.matrix_norm(b, ord=np.inf)
3511
+ 9.0
3512
+ >>> LA.matrix_norm(b, ord=-np.inf)
3513
+ 2.0
3514
+
3515
+ >>> LA.matrix_norm(b, ord=1)
3516
+ 7.0
3517
+ >>> LA.matrix_norm(b, ord=-1)
3518
+ 6.0
3519
+ >>> LA.matrix_norm(b, ord=2)
3520
+ 7.3484692283495345
3521
+ >>> LA.matrix_norm(b, ord=-2)
3522
+ 1.8570331885190563e-016 # may vary
3523
+
3524
+ """
3525
+ x = asanyarray(x)
3526
+ return norm(x, axis=(-2, -1), keepdims=keepdims, ord=ord)
3527
+
3528
+
3529
+ # vector_norm
3530
+
3531
+ def _vector_norm_dispatcher(x, /, *, axis=None, keepdims=None, ord=None):
3532
+ return (x,)
3533
+
3534
+ @array_function_dispatch(_vector_norm_dispatcher)
3535
+ def vector_norm(x, /, *, axis=None, keepdims=False, ord=2):
3536
+ """
3537
+ Computes the vector norm of a vector (or batch of vectors) ``x``.
3538
+
3539
+ This function is Array API compatible.
3540
+
3541
+ Parameters
3542
+ ----------
3543
+ x : array_like
3544
+ Input array.
3545
+ axis : {None, int, 2-tuple of ints}, optional
3546
+ If an integer, ``axis`` specifies the axis (dimension) along which
3547
+ to compute vector norms. If an n-tuple, ``axis`` specifies the axes
3548
+ (dimensions) along which to compute batched vector norms. If ``None``,
3549
+ the vector norm must be computed over all array values (i.e.,
3550
+ equivalent to computing the vector norm of a flattened array).
3551
+ Default: ``None``.
3552
+ keepdims : bool, optional
3553
+ If this is set to True, the axes which are normed over are left in
3554
+ the result as dimensions with size one. Default: False.
3555
+ ord : {int, float, inf, -inf}, optional
3556
+ The order of the norm. For details see the table under ``Notes``
3557
+ in `numpy.linalg.norm`.
3558
+
3559
+ See Also
3560
+ --------
3561
+ numpy.linalg.norm : Generic norm function
3562
+
3563
+ Examples
3564
+ --------
3565
+ >>> from numpy import linalg as LA
3566
+ >>> a = np.arange(9) + 1
3567
+ >>> a
3568
+ array([1, 2, 3, 4, 5, 6, 7, 8, 9])
3569
+ >>> b = a.reshape((3, 3))
3570
+ >>> b
3571
+ array([[1, 2, 3],
3572
+ [4, 5, 6],
3573
+ [7, 8, 9]])
3574
+
3575
+ >>> LA.vector_norm(b)
3576
+ 16.881943016134134
3577
+ >>> LA.vector_norm(b, ord=np.inf)
3578
+ 9.0
3579
+ >>> LA.vector_norm(b, ord=-np.inf)
3580
+ 1.0
3581
+
3582
+ >>> LA.vector_norm(b, ord=0)
3583
+ 9.0
3584
+ >>> LA.vector_norm(b, ord=1)
3585
+ 45.0
3586
+ >>> LA.vector_norm(b, ord=-1)
3587
+ 0.3534857623790153
3588
+ >>> LA.vector_norm(b, ord=2)
3589
+ 16.881943016134134
3590
+ >>> LA.vector_norm(b, ord=-2)
3591
+ 0.8058837395885292
3592
+
3593
+ """
3594
+ x = asanyarray(x)
3595
+ shape = list(x.shape)
3596
+ if axis is None:
3597
+ # Note: np.linalg.norm() doesn't handle 0-D arrays
3598
+ x = x.ravel()
3599
+ _axis = 0
3600
+ elif isinstance(axis, tuple):
3601
+ # Note: The axis argument supports any number of axes, whereas
3602
+ # np.linalg.norm() only supports a single axis for vector norm.
3603
+ normalized_axis = normalize_axis_tuple(axis, x.ndim)
3604
+ rest = tuple(i for i in range(x.ndim) if i not in normalized_axis)
3605
+ newshape = axis + rest
3606
+ x = _core_transpose(x, newshape).reshape(
3607
+ (
3608
+ prod([x.shape[i] for i in axis], dtype=int),
3609
+ *[x.shape[i] for i in rest]
3610
+ )
3611
+ )
3612
+ _axis = 0
3613
+ else:
3614
+ _axis = axis
3615
+
3616
+ res = norm(x, axis=_axis, ord=ord)
3617
+
3618
+ if keepdims:
3619
+ # We can't reuse np.linalg.norm(keepdims) because of the reshape hacks
3620
+ # above to avoid matrix norm logic.
3621
+ _axis = normalize_axis_tuple(
3622
+ range(len(shape)) if axis is None else axis, len(shape)
3623
+ )
3624
+ for i in _axis:
3625
+ shape[i] = 1
3626
+ res = res.reshape(tuple(shape))
3627
+
3628
+ return res
3629
+
3630
+
3631
+ # vecdot
3632
+
3633
+ def _vecdot_dispatcher(x1, x2, /, *, axis=None):
3634
+ return (x1, x2)
3635
+
3636
+ @array_function_dispatch(_vecdot_dispatcher)
3637
+ def vecdot(x1, x2, /, *, axis=-1):
3638
+ """
3639
+ Computes the vector dot product.
3640
+
3641
+ This function is restricted to arguments compatible with the Array API,
3642
+ contrary to :func:`numpy.vecdot`.
3643
+
3644
+ Let :math:`\\mathbf{a}` be a vector in ``x1`` and :math:`\\mathbf{b}` be
3645
+ a corresponding vector in ``x2``. The dot product is defined as:
3646
+
3647
+ .. math::
3648
+ \\mathbf{a} \\cdot \\mathbf{b} = \\sum_{i=0}^{n-1} \\overline{a_i}b_i
3649
+
3650
+ over the dimension specified by ``axis`` and where :math:`\\overline{a_i}`
3651
+ denotes the complex conjugate if :math:`a_i` is complex and the identity
3652
+ otherwise.
3653
+
3654
+ Parameters
3655
+ ----------
3656
+ x1 : array_like
3657
+ First input array.
3658
+ x2 : array_like
3659
+ Second input array.
3660
+ axis : int, optional
3661
+ Axis over which to compute the dot product. Default: ``-1``.
3662
+
3663
+ Returns
3664
+ -------
3665
+ output : ndarray
3666
+ The vector dot product of the input.
3667
+
3668
+ See Also
3669
+ --------
3670
+ numpy.vecdot
3671
+
3672
+ Examples
3673
+ --------
3674
+ Get the projected size along a given normal for an array of vectors.
3675
+
3676
+ >>> v = np.array([[0., 5., 0.], [0., 0., 10.], [0., 6., 8.]])
3677
+ >>> n = np.array([0., 0.6, 0.8])
3678
+ >>> np.linalg.vecdot(v, n)
3679
+ array([ 3., 8., 10.])
3680
+
3681
+ """
3682
+ return _core_vecdot(x1, x2, axis=axis)