_linalg.py 112 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681
  1. """Lite version of scipy.linalg.
  2. Notes
  3. -----
  4. This module is a lite version of the linalg.py module in SciPy which
  5. contains high-level Python interface to the LAPACK library. The lite
  6. version only accesses the following LAPACK functions: dgesv, zgesv,
  7. dgeev, zgeev, dgesdd, zgesdd, dgelsd, zgelsd, dsyevd, zheevd, dgetrf,
  8. zgetrf, dpotrf, zpotrf, dgeqrf, zgeqrf, zungqr, dorgqr.
  9. """
  10. __all__ = ['matrix_power', 'solve', 'tensorsolve', 'tensorinv', 'inv',
  11. 'cholesky', 'eigvals', 'eigvalsh', 'pinv', 'slogdet', 'det',
  12. 'svd', 'svdvals', 'eig', 'eigh', 'lstsq', 'norm', 'qr', 'cond',
  13. 'matrix_rank', 'LinAlgError', 'multi_dot', 'trace', 'diagonal',
  14. 'cross', 'outer', 'tensordot', 'matmul', 'matrix_transpose',
  15. 'matrix_norm', 'vector_norm', 'vecdot']
  16. import functools
  17. import operator
  18. import warnings
  19. from typing import Any, NamedTuple
  20. from numpy._core import (
  21. abs,
  22. add,
  23. all,
  24. amax,
  25. amin,
  26. argsort,
  27. array,
  28. asanyarray,
  29. asarray,
  30. atleast_2d,
  31. cdouble,
  32. complexfloating,
  33. count_nonzero,
  34. csingle,
  35. divide,
  36. dot,
  37. double,
  38. empty,
  39. empty_like,
  40. errstate,
  41. finfo,
  42. inexact,
  43. inf,
  44. intc,
  45. intp,
  46. isfinite,
  47. isnan,
  48. moveaxis,
  49. multiply,
  50. newaxis,
  51. object_,
  52. overrides,
  53. prod,
  54. reciprocal,
  55. sign,
  56. single,
  57. sort,
  58. sqrt,
  59. sum,
  60. swapaxes,
  61. zeros,
  62. )
  63. from numpy._core import (
  64. cross as _core_cross,
  65. )
  66. from numpy._core import (
  67. diagonal as _core_diagonal,
  68. )
  69. from numpy._core import (
  70. matmul as _core_matmul,
  71. )
  72. from numpy._core import (
  73. matrix_transpose as _core_matrix_transpose,
  74. )
  75. from numpy._core import (
  76. outer as _core_outer,
  77. )
  78. from numpy._core import (
  79. tensordot as _core_tensordot,
  80. )
  81. from numpy._core import (
  82. trace as _core_trace,
  83. )
  84. from numpy._core import (
  85. transpose as _core_transpose,
  86. )
  87. from numpy._core import (
  88. vecdot as _core_vecdot,
  89. )
  90. from numpy._globals import _NoValue
  91. from numpy._typing import NDArray
  92. from numpy._utils import set_module
  93. from numpy.lib._twodim_base_impl import eye, triu
  94. from numpy.lib.array_utils import normalize_axis_index, normalize_axis_tuple
  95. from numpy.linalg import _umath_linalg
  96. class EigResult(NamedTuple):
  97. eigenvalues: NDArray[Any]
  98. eigenvectors: NDArray[Any]
  99. class EighResult(NamedTuple):
  100. eigenvalues: NDArray[Any]
  101. eigenvectors: NDArray[Any]
  102. class QRResult(NamedTuple):
  103. Q: NDArray[Any]
  104. R: NDArray[Any]
  105. class SlogdetResult(NamedTuple):
  106. sign: NDArray[Any]
  107. logabsdet: NDArray[Any]
  108. class SVDResult(NamedTuple):
  109. U: NDArray[Any]
  110. S: NDArray[Any]
  111. Vh: NDArray[Any]
  112. array_function_dispatch = functools.partial(
  113. overrides.array_function_dispatch, module='numpy.linalg'
  114. )
  115. fortran_int = intc
  116. @set_module('numpy.linalg')
  117. class LinAlgError(ValueError):
  118. """
  119. Generic Python-exception-derived object raised by linalg functions.
  120. General purpose exception class, derived from Python's ValueError
  121. class, programmatically raised in linalg functions when a Linear
  122. Algebra-related condition would prevent further correct execution of the
  123. function.
  124. Parameters
  125. ----------
  126. None
  127. Examples
  128. --------
  129. >>> from numpy import linalg as LA
  130. >>> LA.inv(np.zeros((2,2)))
  131. Traceback (most recent call last):
  132. File "<stdin>", line 1, in <module>
  133. File "...linalg.py", line 350,
  134. in inv return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
  135. File "...linalg.py", line 249,
  136. in solve
  137. raise LinAlgError('Singular matrix')
  138. numpy.linalg.LinAlgError: Singular matrix
  139. """
  140. def _raise_linalgerror_singular(err, flag):
  141. raise LinAlgError("Singular matrix")
  142. def _raise_linalgerror_nonposdef(err, flag):
  143. raise LinAlgError("Matrix is not positive definite")
  144. def _raise_linalgerror_eigenvalues_nonconvergence(err, flag):
  145. raise LinAlgError("Eigenvalues did not converge")
  146. def _raise_linalgerror_svd_nonconvergence(err, flag):
  147. raise LinAlgError("SVD did not converge")
  148. def _raise_linalgerror_lstsq(err, flag):
  149. raise LinAlgError("SVD did not converge in Linear Least Squares")
  150. def _raise_linalgerror_qr(err, flag):
  151. raise LinAlgError("Incorrect argument found while performing "
  152. "QR factorization")
  153. def _makearray(a):
  154. new = asarray(a)
  155. wrap = getattr(a, "__array_wrap__", new.__array_wrap__)
  156. return new, wrap
  157. def isComplexType(t):
  158. return issubclass(t, complexfloating)
  159. _real_types_map = {single: single,
  160. double: double,
  161. csingle: single,
  162. cdouble: double}
  163. _complex_types_map = {single: csingle,
  164. double: cdouble,
  165. csingle: csingle,
  166. cdouble: cdouble}
  167. def _realType(t, default=double):
  168. return _real_types_map.get(t, default)
  169. def _complexType(t, default=cdouble):
  170. return _complex_types_map.get(t, default)
  171. def _commonType(*arrays):
  172. # in lite version, use higher precision (always double or cdouble)
  173. result_type = single
  174. is_complex = False
  175. for a in arrays:
  176. type_ = a.dtype.type
  177. if issubclass(type_, inexact):
  178. if isComplexType(type_):
  179. is_complex = True
  180. rt = _realType(type_, default=None)
  181. if rt is double:
  182. result_type = double
  183. elif rt is None:
  184. # unsupported inexact scalar
  185. raise TypeError(f"array type {a.dtype.name} is unsupported in linalg")
  186. else:
  187. result_type = double
  188. if is_complex:
  189. result_type = _complex_types_map[result_type]
  190. return cdouble, result_type
  191. else:
  192. return double, result_type
  193. def _to_native_byte_order(*arrays):
  194. ret = []
  195. for arr in arrays:
  196. if arr.dtype.byteorder not in ('=', '|'):
  197. ret.append(asarray(arr, dtype=arr.dtype.newbyteorder('=')))
  198. else:
  199. ret.append(arr)
  200. if len(ret) == 1:
  201. return ret[0]
  202. else:
  203. return ret
  204. def _assert_2d(*arrays):
  205. for a in arrays:
  206. if a.ndim != 2:
  207. raise LinAlgError('%d-dimensional array given. Array must be '
  208. 'two-dimensional' % a.ndim)
  209. def _assert_stacked_2d(*arrays):
  210. for a in arrays:
  211. if a.ndim < 2:
  212. raise LinAlgError('%d-dimensional array given. Array must be '
  213. 'at least two-dimensional' % a.ndim)
  214. def _assert_stacked_square(*arrays):
  215. for a in arrays:
  216. try:
  217. m, n = a.shape[-2:]
  218. except ValueError:
  219. raise LinAlgError('%d-dimensional array given. Array must be '
  220. 'at least two-dimensional' % a.ndim)
  221. if m != n:
  222. raise LinAlgError('Last 2 dimensions of the array must be square')
  223. def _assert_finite(*arrays):
  224. for a in arrays:
  225. if not isfinite(a).all():
  226. raise LinAlgError("Array must not contain infs or NaNs")
  227. def _is_empty_2d(arr):
  228. # check size first for efficiency
  229. return arr.size == 0 and prod(arr.shape[-2:]) == 0
  230. def transpose(a):
  231. """
  232. Transpose each matrix in a stack of matrices.
  233. Unlike np.transpose, this only swaps the last two axes, rather than all of
  234. them
  235. Parameters
  236. ----------
  237. a : (...,M,N) array_like
  238. Returns
  239. -------
  240. aT : (...,N,M) ndarray
  241. """
  242. return swapaxes(a, -1, -2)
  243. # Linear equations
  244. def _tensorsolve_dispatcher(a, b, axes=None):
  245. return (a, b)
  246. @array_function_dispatch(_tensorsolve_dispatcher)
  247. def tensorsolve(a, b, axes=None):
  248. """
  249. Solve the tensor equation ``a x = b`` for x.
  250. It is assumed that all indices of `x` are summed over in the product,
  251. together with the rightmost indices of `a`, as is done in, for example,
  252. ``tensordot(a, x, axes=x.ndim)``.
  253. Parameters
  254. ----------
  255. a : array_like
  256. Coefficient tensor, of shape ``b.shape + Q``. `Q`, a tuple, equals
  257. the shape of that sub-tensor of `a` consisting of the appropriate
  258. number of its rightmost indices, and must be such that
  259. ``prod(Q) == prod(b.shape)`` (in which sense `a` is said to be
  260. 'square').
  261. b : array_like
  262. Right-hand tensor, which can be of any shape.
  263. axes : tuple of ints, optional
  264. Axes in `a` to reorder to the right, before inversion.
  265. If None (default), no reordering is done.
  266. Returns
  267. -------
  268. x : ndarray, shape Q
  269. Raises
  270. ------
  271. LinAlgError
  272. If `a` is singular or not 'square' (in the above sense).
  273. See Also
  274. --------
  275. numpy.tensordot, tensorinv, numpy.einsum
  276. Examples
  277. --------
  278. >>> import numpy as np
  279. >>> a = np.eye(2*3*4)
  280. >>> a.shape = (2*3, 4, 2, 3, 4)
  281. >>> rng = np.random.default_rng()
  282. >>> b = rng.normal(size=(2*3, 4))
  283. >>> x = np.linalg.tensorsolve(a, b)
  284. >>> x.shape
  285. (2, 3, 4)
  286. >>> np.allclose(np.tensordot(a, x, axes=3), b)
  287. True
  288. """
  289. a, wrap = _makearray(a)
  290. b = asarray(b)
  291. an = a.ndim
  292. if axes is not None:
  293. allaxes = list(range(an))
  294. for k in axes:
  295. allaxes.remove(k)
  296. allaxes.insert(an, k)
  297. a = a.transpose(allaxes)
  298. oldshape = a.shape[-(an - b.ndim):]
  299. prod = 1
  300. for k in oldshape:
  301. prod *= k
  302. if a.size != prod ** 2:
  303. raise LinAlgError(
  304. "Input arrays must satisfy the requirement \
  305. prod(a.shape[b.ndim:]) == prod(a.shape[:b.ndim])"
  306. )
  307. a = a.reshape(prod, prod)
  308. b = b.ravel()
  309. res = wrap(solve(a, b))
  310. res.shape = oldshape
  311. return res
  312. def _solve_dispatcher(a, b):
  313. return (a, b)
  314. @array_function_dispatch(_solve_dispatcher)
  315. def solve(a, b):
  316. """
  317. Solve a linear matrix equation, or system of linear scalar equations.
  318. Computes the "exact" solution, `x`, of the well-determined, i.e., full
  319. rank, linear matrix equation `ax = b`.
  320. Parameters
  321. ----------
  322. a : (..., M, M) array_like
  323. Coefficient matrix.
  324. b : {(M,), (..., M, K)}, array_like
  325. Ordinate or "dependent variable" values.
  326. Returns
  327. -------
  328. x : {(..., M,), (..., M, K)} ndarray
  329. Solution to the system a x = b. Returned shape is (..., M) if b is
  330. shape (M,) and (..., M, K) if b is (..., M, K), where the "..." part is
  331. broadcasted between a and b.
  332. Raises
  333. ------
  334. LinAlgError
  335. If `a` is singular or not square.
  336. See Also
  337. --------
  338. scipy.linalg.solve : Similar function in SciPy.
  339. Notes
  340. -----
  341. Broadcasting rules apply, see the `numpy.linalg` documentation for
  342. details.
  343. The solutions are computed using LAPACK routine ``_gesv``.
  344. `a` must be square and of full-rank, i.e., all rows (or, equivalently,
  345. columns) must be linearly independent; if either is not true, use
  346. `lstsq` for the least-squares best "solution" of the
  347. system/equation.
  348. .. versionchanged:: 2.0
  349. The b array is only treated as a shape (M,) column vector if it is
  350. exactly 1-dimensional. In all other instances it is treated as a stack
  351. of (M, K) matrices. Previously b would be treated as a stack of (M,)
  352. vectors if b.ndim was equal to a.ndim - 1.
  353. References
  354. ----------
  355. .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
  356. FL, Academic Press, Inc., 1980, pg. 22.
  357. Examples
  358. --------
  359. Solve the system of equations:
  360. ``x0 + 2 * x1 = 1`` and
  361. ``3 * x0 + 5 * x1 = 2``:
  362. >>> import numpy as np
  363. >>> a = np.array([[1, 2], [3, 5]])
  364. >>> b = np.array([1, 2])
  365. >>> x = np.linalg.solve(a, b)
  366. >>> x
  367. array([-1., 1.])
  368. Check that the solution is correct:
  369. >>> np.allclose(np.dot(a, x), b)
  370. True
  371. """
  372. a, _ = _makearray(a)
  373. _assert_stacked_square(a)
  374. b, wrap = _makearray(b)
  375. t, result_t = _commonType(a, b)
  376. # We use the b = (..., M,) logic, only if the number of extra dimensions
  377. # match exactly
  378. if b.ndim == 1:
  379. gufunc = _umath_linalg.solve1
  380. else:
  381. gufunc = _umath_linalg.solve
  382. signature = 'DD->D' if isComplexType(t) else 'dd->d'
  383. with errstate(call=_raise_linalgerror_singular, invalid='call',
  384. over='ignore', divide='ignore', under='ignore'):
  385. r = gufunc(a, b, signature=signature)
  386. return wrap(r.astype(result_t, copy=False))
  387. def _tensorinv_dispatcher(a, ind=None):
  388. return (a,)
  389. @array_function_dispatch(_tensorinv_dispatcher)
  390. def tensorinv(a, ind=2):
  391. """
  392. Compute the 'inverse' of an N-dimensional array.
  393. The result is an inverse for `a` relative to the tensordot operation
  394. ``tensordot(a, b, ind)``, i. e., up to floating-point accuracy,
  395. ``tensordot(tensorinv(a), a, ind)`` is the "identity" tensor for the
  396. tensordot operation.
  397. Parameters
  398. ----------
  399. a : array_like
  400. Tensor to 'invert'. Its shape must be 'square', i. e.,
  401. ``prod(a.shape[:ind]) == prod(a.shape[ind:])``.
  402. ind : int, optional
  403. Number of first indices that are involved in the inverse sum.
  404. Must be a positive integer, default is 2.
  405. Returns
  406. -------
  407. b : ndarray
  408. `a`'s tensordot inverse, shape ``a.shape[ind:] + a.shape[:ind]``.
  409. Raises
  410. ------
  411. LinAlgError
  412. If `a` is singular or not 'square' (in the above sense).
  413. See Also
  414. --------
  415. numpy.tensordot, tensorsolve
  416. Examples
  417. --------
  418. >>> import numpy as np
  419. >>> a = np.eye(4*6)
  420. >>> a.shape = (4, 6, 8, 3)
  421. >>> ainv = np.linalg.tensorinv(a, ind=2)
  422. >>> ainv.shape
  423. (8, 3, 4, 6)
  424. >>> rng = np.random.default_rng()
  425. >>> b = rng.normal(size=(4, 6))
  426. >>> np.allclose(np.tensordot(ainv, b), np.linalg.tensorsolve(a, b))
  427. True
  428. >>> a = np.eye(4*6)
  429. >>> a.shape = (24, 8, 3)
  430. >>> ainv = np.linalg.tensorinv(a, ind=1)
  431. >>> ainv.shape
  432. (8, 3, 24)
  433. >>> rng = np.random.default_rng()
  434. >>> b = rng.normal(size=24)
  435. >>> np.allclose(np.tensordot(ainv, b, 1), np.linalg.tensorsolve(a, b))
  436. True
  437. """
  438. a = asarray(a)
  439. oldshape = a.shape
  440. prod = 1
  441. if ind > 0:
  442. invshape = oldshape[ind:] + oldshape[:ind]
  443. for k in oldshape[ind:]:
  444. prod *= k
  445. else:
  446. raise ValueError("Invalid ind argument.")
  447. a = a.reshape(prod, -1)
  448. ia = inv(a)
  449. return ia.reshape(*invshape)
  450. # Matrix inversion
  451. def _unary_dispatcher(a):
  452. return (a,)
  453. @array_function_dispatch(_unary_dispatcher)
  454. def inv(a):
  455. """
  456. Compute the inverse of a matrix.
  457. Given a square matrix `a`, return the matrix `ainv` satisfying
  458. ``a @ ainv = ainv @ a = eye(a.shape[0])``.
  459. Parameters
  460. ----------
  461. a : (..., M, M) array_like
  462. Matrix to be inverted.
  463. Returns
  464. -------
  465. ainv : (..., M, M) ndarray or matrix
  466. Inverse of the matrix `a`.
  467. Raises
  468. ------
  469. LinAlgError
  470. If `a` is not square or inversion fails.
  471. See Also
  472. --------
  473. scipy.linalg.inv : Similar function in SciPy.
  474. numpy.linalg.cond : Compute the condition number of a matrix.
  475. numpy.linalg.svd : Compute the singular value decomposition of a matrix.
  476. Notes
  477. -----
  478. Broadcasting rules apply, see the `numpy.linalg` documentation for
  479. details.
  480. If `a` is detected to be singular, a `LinAlgError` is raised. If `a` is
  481. ill-conditioned, a `LinAlgError` may or may not be raised, and results may
  482. be inaccurate due to floating-point errors.
  483. References
  484. ----------
  485. .. [1] Wikipedia, "Condition number",
  486. https://en.wikipedia.org/wiki/Condition_number
  487. Examples
  488. --------
  489. >>> import numpy as np
  490. >>> from numpy.linalg import inv
  491. >>> a = np.array([[1., 2.], [3., 4.]])
  492. >>> ainv = inv(a)
  493. >>> np.allclose(a @ ainv, np.eye(2))
  494. True
  495. >>> np.allclose(ainv @ a, np.eye(2))
  496. True
  497. If a is a matrix object, then the return value is a matrix as well:
  498. >>> ainv = inv(np.matrix(a))
  499. >>> ainv
  500. matrix([[-2. , 1. ],
  501. [ 1.5, -0.5]])
  502. Inverses of several matrices can be computed at once:
  503. >>> a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]])
  504. >>> inv(a)
  505. array([[[-2. , 1. ],
  506. [ 1.5 , -0.5 ]],
  507. [[-1.25, 0.75],
  508. [ 0.75, -0.25]]])
  509. If a matrix is close to singular, the computed inverse may not satisfy
  510. ``a @ ainv = ainv @ a = eye(a.shape[0])`` even if a `LinAlgError`
  511. is not raised:
  512. >>> a = np.array([[2,4,6],[2,0,2],[6,8,14]])
  513. >>> inv(a) # No errors raised
  514. array([[-1.12589991e+15, -5.62949953e+14, 5.62949953e+14],
  515. [-1.12589991e+15, -5.62949953e+14, 5.62949953e+14],
  516. [ 1.12589991e+15, 5.62949953e+14, -5.62949953e+14]])
  517. >>> a @ inv(a)
  518. array([[ 0. , -0.5 , 0. ], # may vary
  519. [-0.5 , 0.625, 0.25 ],
  520. [ 0. , 0. , 1. ]])
  521. To detect ill-conditioned matrices, you can use `numpy.linalg.cond` to
  522. compute its *condition number* [1]_. The larger the condition number, the
  523. more ill-conditioned the matrix is. As a rule of thumb, if the condition
  524. number ``cond(a) = 10**k``, then you may lose up to ``k`` digits of
  525. accuracy on top of what would be lost to the numerical method due to loss
  526. of precision from arithmetic methods.
  527. >>> from numpy.linalg import cond
  528. >>> cond(a)
  529. np.float64(8.659885634118668e+17) # may vary
  530. It is also possible to detect ill-conditioning by inspecting the matrix's
  531. singular values directly. The ratio between the largest and the smallest
  532. singular value is the condition number:
  533. >>> from numpy.linalg import svd
  534. >>> sigma = svd(a, compute_uv=False) # Do not compute singular vectors
  535. >>> sigma.max()/sigma.min()
  536. 8.659885634118668e+17 # may vary
  537. """
  538. a, wrap = _makearray(a)
  539. _assert_stacked_square(a)
  540. t, result_t = _commonType(a)
  541. signature = 'D->D' if isComplexType(t) else 'd->d'
  542. with errstate(call=_raise_linalgerror_singular, invalid='call',
  543. over='ignore', divide='ignore', under='ignore'):
  544. ainv = _umath_linalg.inv(a, signature=signature)
  545. return wrap(ainv.astype(result_t, copy=False))
  546. def _matrix_power_dispatcher(a, n):
  547. return (a,)
  548. @array_function_dispatch(_matrix_power_dispatcher)
  549. def matrix_power(a, n):
  550. """
  551. Raise a square matrix to the (integer) power `n`.
  552. For positive integers `n`, the power is computed by repeated matrix
  553. squarings and matrix multiplications. If ``n == 0``, the identity matrix
  554. of the same shape as M is returned. If ``n < 0``, the inverse
  555. is computed and then raised to the ``abs(n)``.
  556. .. note:: Stacks of object matrices are not currently supported.
  557. Parameters
  558. ----------
  559. a : (..., M, M) array_like
  560. Matrix to be "powered".
  561. n : int
  562. The exponent can be any integer or long integer, positive,
  563. negative, or zero.
  564. Returns
  565. -------
  566. a**n : (..., M, M) ndarray or matrix object
  567. The return value is the same shape and type as `M`;
  568. if the exponent is positive or zero then the type of the
  569. elements is the same as those of `M`. If the exponent is
  570. negative the elements are floating-point.
  571. Raises
  572. ------
  573. LinAlgError
  574. For matrices that are not square or that (for negative powers) cannot
  575. be inverted numerically.
  576. Examples
  577. --------
  578. >>> import numpy as np
  579. >>> from numpy.linalg import matrix_power
  580. >>> i = np.array([[0, 1], [-1, 0]]) # matrix equiv. of the imaginary unit
  581. >>> matrix_power(i, 3) # should = -i
  582. array([[ 0, -1],
  583. [ 1, 0]])
  584. >>> matrix_power(i, 0)
  585. array([[1, 0],
  586. [0, 1]])
  587. >>> matrix_power(i, -3) # should = 1/(-i) = i, but w/ f.p. elements
  588. array([[ 0., 1.],
  589. [-1., 0.]])
  590. Somewhat more sophisticated example
  591. >>> q = np.zeros((4, 4))
  592. >>> q[0:2, 0:2] = -i
  593. >>> q[2:4, 2:4] = i
  594. >>> q # one of the three quaternion units not equal to 1
  595. array([[ 0., -1., 0., 0.],
  596. [ 1., 0., 0., 0.],
  597. [ 0., 0., 0., 1.],
  598. [ 0., 0., -1., 0.]])
  599. >>> matrix_power(q, 2) # = -np.eye(4)
  600. array([[-1., 0., 0., 0.],
  601. [ 0., -1., 0., 0.],
  602. [ 0., 0., -1., 0.],
  603. [ 0., 0., 0., -1.]])
  604. """
  605. a = asanyarray(a)
  606. _assert_stacked_square(a)
  607. try:
  608. n = operator.index(n)
  609. except TypeError as e:
  610. raise TypeError("exponent must be an integer") from e
  611. # Fall back on dot for object arrays. Object arrays are not supported by
  612. # the current implementation of matmul using einsum
  613. if a.dtype != object:
  614. fmatmul = matmul
  615. elif a.ndim == 2:
  616. fmatmul = dot
  617. else:
  618. raise NotImplementedError(
  619. "matrix_power not supported for stacks of object arrays")
  620. if n == 0:
  621. a = empty_like(a)
  622. a[...] = eye(a.shape[-2], dtype=a.dtype)
  623. return a
  624. elif n < 0:
  625. a = inv(a)
  626. n = abs(n)
  627. # short-cuts.
  628. if n == 1:
  629. return a
  630. elif n == 2:
  631. return fmatmul(a, a)
  632. elif n == 3:
  633. return fmatmul(fmatmul(a, a), a)
  634. # Use binary decomposition to reduce the number of matrix multiplications.
  635. # Here, we iterate over the bits of n, from LSB to MSB, raise `a` to
  636. # increasing powers of 2, and multiply into the result as needed.
  637. z = result = None
  638. while n > 0:
  639. z = a if z is None else fmatmul(z, z)
  640. n, bit = divmod(n, 2)
  641. if bit:
  642. result = z if result is None else fmatmul(result, z)
  643. return result
  644. # Cholesky decomposition
  645. def _cholesky_dispatcher(a, /, *, upper=None):
  646. return (a,)
  647. @array_function_dispatch(_cholesky_dispatcher)
  648. def cholesky(a, /, *, upper=False):
  649. """
  650. Cholesky decomposition.
  651. Return the lower or upper Cholesky decomposition, ``L * L.H`` or
  652. ``U.H * U``, of the square matrix ``a``, where ``L`` is lower-triangular,
  653. ``U`` is upper-triangular, and ``.H`` is the conjugate transpose operator
  654. (which is the ordinary transpose if ``a`` is real-valued). ``a`` must be
  655. Hermitian (symmetric if real-valued) and positive-definite. No checking is
  656. performed to verify whether ``a`` is Hermitian or not. In addition, only
  657. the lower or upper-triangular and diagonal elements of ``a`` are used.
  658. Only ``L`` or ``U`` is actually returned.
  659. Parameters
  660. ----------
  661. a : (..., M, M) array_like
  662. Hermitian (symmetric if all elements are real), positive-definite
  663. input matrix.
  664. upper : bool
  665. If ``True``, the result must be the upper-triangular Cholesky factor.
  666. If ``False``, the result must be the lower-triangular Cholesky factor.
  667. Default: ``False``.
  668. Returns
  669. -------
  670. L : (..., M, M) array_like
  671. Lower or upper-triangular Cholesky factor of `a`. Returns a matrix
  672. object if `a` is a matrix object.
  673. Raises
  674. ------
  675. LinAlgError
  676. If the decomposition fails, for example, if `a` is not
  677. positive-definite.
  678. See Also
  679. --------
  680. scipy.linalg.cholesky : Similar function in SciPy.
  681. scipy.linalg.cholesky_banded : Cholesky decompose a banded Hermitian
  682. positive-definite matrix.
  683. scipy.linalg.cho_factor : Cholesky decomposition of a matrix, to use in
  684. `scipy.linalg.cho_solve`.
  685. Notes
  686. -----
  687. Broadcasting rules apply, see the `numpy.linalg` documentation for
  688. details.
  689. The Cholesky decomposition is often used as a fast way of solving
  690. .. math:: A \\mathbf{x} = \\mathbf{b}
  691. (when `A` is both Hermitian/symmetric and positive-definite).
  692. First, we solve for :math:`\\mathbf{y}` in
  693. .. math:: L \\mathbf{y} = \\mathbf{b},
  694. and then for :math:`\\mathbf{x}` in
  695. .. math:: L^{H} \\mathbf{x} = \\mathbf{y}.
  696. Examples
  697. --------
  698. >>> import numpy as np
  699. >>> A = np.array([[1,-2j],[2j,5]])
  700. >>> A
  701. array([[ 1.+0.j, -0.-2.j],
  702. [ 0.+2.j, 5.+0.j]])
  703. >>> L = np.linalg.cholesky(A)
  704. >>> L
  705. array([[1.+0.j, 0.+0.j],
  706. [0.+2.j, 1.+0.j]])
  707. >>> np.dot(L, L.T.conj()) # verify that L * L.H = A
  708. array([[1.+0.j, 0.-2.j],
  709. [0.+2.j, 5.+0.j]])
  710. >>> A = [[1,-2j],[2j,5]] # what happens if A is only array_like?
  711. >>> np.linalg.cholesky(A) # an ndarray object is returned
  712. array([[1.+0.j, 0.+0.j],
  713. [0.+2.j, 1.+0.j]])
  714. >>> # But a matrix object is returned if A is a matrix object
  715. >>> np.linalg.cholesky(np.matrix(A))
  716. matrix([[ 1.+0.j, 0.+0.j],
  717. [ 0.+2.j, 1.+0.j]])
  718. >>> # The upper-triangular Cholesky factor can also be obtained.
  719. >>> np.linalg.cholesky(A, upper=True)
  720. array([[1.-0.j, 0.-2.j],
  721. [0.-0.j, 1.-0.j]])
  722. """
  723. gufunc = _umath_linalg.cholesky_up if upper else _umath_linalg.cholesky_lo
  724. a, wrap = _makearray(a)
  725. _assert_stacked_square(a)
  726. t, result_t = _commonType(a)
  727. signature = 'D->D' if isComplexType(t) else 'd->d'
  728. with errstate(call=_raise_linalgerror_nonposdef, invalid='call',
  729. over='ignore', divide='ignore', under='ignore'):
  730. r = gufunc(a, signature=signature)
  731. return wrap(r.astype(result_t, copy=False))
  732. # outer product
  733. def _outer_dispatcher(x1, x2):
  734. return (x1, x2)
  735. @array_function_dispatch(_outer_dispatcher)
  736. def outer(x1, x2, /):
  737. """
  738. Compute the outer product of two vectors.
  739. This function is Array API compatible. Compared to ``np.outer``
  740. it accepts 1-dimensional inputs only.
  741. Parameters
  742. ----------
  743. x1 : (M,) array_like
  744. One-dimensional input array of size ``N``.
  745. Must have a numeric data type.
  746. x2 : (N,) array_like
  747. One-dimensional input array of size ``M``.
  748. Must have a numeric data type.
  749. Returns
  750. -------
  751. out : (M, N) ndarray
  752. ``out[i, j] = a[i] * b[j]``
  753. See also
  754. --------
  755. outer
  756. Examples
  757. --------
  758. Make a (*very* coarse) grid for computing a Mandelbrot set:
  759. >>> rl = np.linalg.outer(np.ones((5,)), np.linspace(-2, 2, 5))
  760. >>> rl
  761. array([[-2., -1., 0., 1., 2.],
  762. [-2., -1., 0., 1., 2.],
  763. [-2., -1., 0., 1., 2.],
  764. [-2., -1., 0., 1., 2.],
  765. [-2., -1., 0., 1., 2.]])
  766. >>> im = np.linalg.outer(1j*np.linspace(2, -2, 5), np.ones((5,)))
  767. >>> im
  768. array([[0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j],
  769. [0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j],
  770. [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
  771. [0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j],
  772. [0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]])
  773. >>> grid = rl + im
  774. >>> grid
  775. array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j],
  776. [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j],
  777. [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j],
  778. [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j],
  779. [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]])
  780. An example using a "vector" of letters:
  781. >>> x = np.array(['a', 'b', 'c'], dtype=object)
  782. >>> np.linalg.outer(x, [1, 2, 3])
  783. array([['a', 'aa', 'aaa'],
  784. ['b', 'bb', 'bbb'],
  785. ['c', 'cc', 'ccc']], dtype=object)
  786. """
  787. x1 = asanyarray(x1)
  788. x2 = asanyarray(x2)
  789. if x1.ndim != 1 or x2.ndim != 1:
  790. raise ValueError(
  791. "Input arrays must be one-dimensional, but they are "
  792. f"{x1.ndim=} and {x2.ndim=}."
  793. )
  794. return _core_outer(x1, x2, out=None)
  795. # QR decomposition
  796. def _qr_dispatcher(a, mode=None):
  797. return (a,)
  798. @array_function_dispatch(_qr_dispatcher)
  799. def qr(a, mode='reduced'):
  800. """
  801. Compute the qr factorization of a matrix.
  802. Factor the matrix `a` as *qr*, where `q` is orthonormal and `r` is
  803. upper-triangular.
  804. Parameters
  805. ----------
  806. a : array_like, shape (..., M, N)
  807. An array-like object with the dimensionality of at least 2.
  808. mode : {'reduced', 'complete', 'r', 'raw'}, optional, default: 'reduced'
  809. If K = min(M, N), then
  810. * 'reduced' : returns Q, R with dimensions (..., M, K), (..., K, N)
  811. * 'complete' : returns Q, R with dimensions (..., M, M), (..., M, N)
  812. * 'r' : returns R only with dimensions (..., K, N)
  813. * 'raw' : returns h, tau with dimensions (..., N, M), (..., K,)
  814. The options 'reduced', 'complete, and 'raw' are new in numpy 1.8,
  815. see the notes for more information. The default is 'reduced', and to
  816. maintain backward compatibility with earlier versions of numpy both
  817. it and the old default 'full' can be omitted. Note that array h
  818. returned in 'raw' mode is transposed for calling Fortran. The
  819. 'economic' mode is deprecated. The modes 'full' and 'economic' may
  820. be passed using only the first letter for backwards compatibility,
  821. but all others must be spelled out. See the Notes for more
  822. explanation.
  823. Returns
  824. -------
  825. When mode is 'reduced' or 'complete', the result will be a namedtuple with
  826. the attributes `Q` and `R`.
  827. Q : ndarray of float or complex, optional
  828. A matrix with orthonormal columns. When mode = 'complete' the
  829. result is an orthogonal/unitary matrix depending on whether or not
  830. a is real/complex. The determinant may be either +/- 1 in that
  831. case. In case the number of dimensions in the input array is
  832. greater than 2 then a stack of the matrices with above properties
  833. is returned.
  834. R : ndarray of float or complex, optional
  835. The upper-triangular matrix or a stack of upper-triangular
  836. matrices if the number of dimensions in the input array is greater
  837. than 2.
  838. (h, tau) : ndarrays of np.double or np.cdouble, optional
  839. The array h contains the Householder reflectors that generate q
  840. along with r. The tau array contains scaling factors for the
  841. reflectors. In the deprecated 'economic' mode only h is returned.
  842. Raises
  843. ------
  844. LinAlgError
  845. If factoring fails.
  846. See Also
  847. --------
  848. scipy.linalg.qr : Similar function in SciPy.
  849. scipy.linalg.rq : Compute RQ decomposition of a matrix.
  850. Notes
  851. -----
  852. This is an interface to the LAPACK routines ``dgeqrf``, ``zgeqrf``,
  853. ``dorgqr``, and ``zungqr``.
  854. For more information on the qr factorization, see for example:
  855. https://en.wikipedia.org/wiki/QR_factorization
  856. Subclasses of `ndarray` are preserved except for the 'raw' mode. So if
  857. `a` is of type `matrix`, all the return values will be matrices too.
  858. New 'reduced', 'complete', and 'raw' options for mode were added in
  859. NumPy 1.8.0 and the old option 'full' was made an alias of 'reduced'. In
  860. addition the options 'full' and 'economic' were deprecated. Because
  861. 'full' was the previous default and 'reduced' is the new default,
  862. backward compatibility can be maintained by letting `mode` default.
  863. The 'raw' option was added so that LAPACK routines that can multiply
  864. arrays by q using the Householder reflectors can be used. Note that in
  865. this case the returned arrays are of type np.double or np.cdouble and
  866. the h array is transposed to be FORTRAN compatible. No routines using
  867. the 'raw' return are currently exposed by numpy, but some are available
  868. in lapack_lite and just await the necessary work.
  869. Examples
  870. --------
  871. >>> import numpy as np
  872. >>> rng = np.random.default_rng()
  873. >>> a = rng.normal(size=(9, 6))
  874. >>> Q, R = np.linalg.qr(a)
  875. >>> np.allclose(a, np.dot(Q, R)) # a does equal QR
  876. True
  877. >>> R2 = np.linalg.qr(a, mode='r')
  878. >>> np.allclose(R, R2) # mode='r' returns the same R as mode='full'
  879. True
  880. >>> a = np.random.normal(size=(3, 2, 2)) # Stack of 2 x 2 matrices as input
  881. >>> Q, R = np.linalg.qr(a)
  882. >>> Q.shape
  883. (3, 2, 2)
  884. >>> R.shape
  885. (3, 2, 2)
  886. >>> np.allclose(a, np.matmul(Q, R))
  887. True
  888. Example illustrating a common use of `qr`: solving of least squares
  889. problems
  890. What are the least-squares-best `m` and `y0` in ``y = y0 + mx`` for
  891. the following data: {(0,1), (1,0), (1,2), (2,1)}. (Graph the points
  892. and you'll see that it should be y0 = 0, m = 1.) The answer is provided
  893. by solving the over-determined matrix equation ``Ax = b``, where::
  894. A = array([[0, 1], [1, 1], [1, 1], [2, 1]])
  895. x = array([[y0], [m]])
  896. b = array([[1], [0], [2], [1]])
  897. If A = QR such that Q is orthonormal (which is always possible via
  898. Gram-Schmidt), then ``x = inv(R) * (Q.T) * b``. (In numpy practice,
  899. however, we simply use `lstsq`.)
  900. >>> A = np.array([[0, 1], [1, 1], [1, 1], [2, 1]])
  901. >>> A
  902. array([[0, 1],
  903. [1, 1],
  904. [1, 1],
  905. [2, 1]])
  906. >>> b = np.array([1, 2, 2, 3])
  907. >>> Q, R = np.linalg.qr(A)
  908. >>> p = np.dot(Q.T, b)
  909. >>> np.dot(np.linalg.inv(R), p)
  910. array([ 1., 1.])
  911. """
  912. if mode not in ('reduced', 'complete', 'r', 'raw'):
  913. if mode in ('f', 'full'):
  914. # 2013-04-01, 1.8
  915. msg = (
  916. "The 'full' option is deprecated in favor of 'reduced'.\n"
  917. "For backward compatibility let mode default."
  918. )
  919. warnings.warn(msg, DeprecationWarning, stacklevel=2)
  920. mode = 'reduced'
  921. elif mode in ('e', 'economic'):
  922. # 2013-04-01, 1.8
  923. msg = "The 'economic' option is deprecated."
  924. warnings.warn(msg, DeprecationWarning, stacklevel=2)
  925. mode = 'economic'
  926. else:
  927. raise ValueError(f"Unrecognized mode '{mode}'")
  928. a, wrap = _makearray(a)
  929. _assert_stacked_2d(a)
  930. m, n = a.shape[-2:]
  931. t, result_t = _commonType(a)
  932. a = a.astype(t, copy=True)
  933. a = _to_native_byte_order(a)
  934. mn = min(m, n)
  935. signature = 'D->D' if isComplexType(t) else 'd->d'
  936. with errstate(call=_raise_linalgerror_qr, invalid='call',
  937. over='ignore', divide='ignore', under='ignore'):
  938. tau = _umath_linalg.qr_r_raw(a, signature=signature)
  939. # handle modes that don't return q
  940. if mode == 'r':
  941. r = triu(a[..., :mn, :])
  942. r = r.astype(result_t, copy=False)
  943. return wrap(r)
  944. if mode == 'raw':
  945. q = transpose(a)
  946. q = q.astype(result_t, copy=False)
  947. tau = tau.astype(result_t, copy=False)
  948. return wrap(q), tau
  949. if mode == 'economic':
  950. a = a.astype(result_t, copy=False)
  951. return wrap(a)
  952. # mc is the number of columns in the resulting q
  953. # matrix. If the mode is complete then it is
  954. # same as number of rows, and if the mode is reduced,
  955. # then it is the minimum of number of rows and columns.
  956. if mode == 'complete' and m > n:
  957. mc = m
  958. gufunc = _umath_linalg.qr_complete
  959. else:
  960. mc = mn
  961. gufunc = _umath_linalg.qr_reduced
  962. signature = 'DD->D' if isComplexType(t) else 'dd->d'
  963. with errstate(call=_raise_linalgerror_qr, invalid='call',
  964. over='ignore', divide='ignore', under='ignore'):
  965. q = gufunc(a, tau, signature=signature)
  966. r = triu(a[..., :mc, :])
  967. q = q.astype(result_t, copy=False)
  968. r = r.astype(result_t, copy=False)
  969. return QRResult(wrap(q), wrap(r))
  970. # Eigenvalues
  971. @array_function_dispatch(_unary_dispatcher)
  972. def eigvals(a):
  973. """
  974. Compute the eigenvalues of a general matrix.
  975. Main difference between `eigvals` and `eig`: the eigenvectors aren't
  976. returned.
  977. Parameters
  978. ----------
  979. a : (..., M, M) array_like
  980. A complex- or real-valued matrix whose eigenvalues will be computed.
  981. Returns
  982. -------
  983. w : (..., M,) ndarray
  984. The eigenvalues, each repeated according to its multiplicity.
  985. They are not necessarily ordered, nor are they necessarily
  986. real for real matrices.
  987. Raises
  988. ------
  989. LinAlgError
  990. If the eigenvalue computation does not converge.
  991. See Also
  992. --------
  993. eig : eigenvalues and right eigenvectors of general arrays
  994. eigvalsh : eigenvalues of real symmetric or complex Hermitian
  995. (conjugate symmetric) arrays.
  996. eigh : eigenvalues and eigenvectors of real symmetric or complex
  997. Hermitian (conjugate symmetric) arrays.
  998. scipy.linalg.eigvals : Similar function in SciPy.
  999. Notes
  1000. -----
  1001. Broadcasting rules apply, see the `numpy.linalg` documentation for
  1002. details.
  1003. This is implemented using the ``_geev`` LAPACK routines which compute
  1004. the eigenvalues and eigenvectors of general square arrays.
  1005. Examples
  1006. --------
  1007. Illustration, using the fact that the eigenvalues of a diagonal matrix
  1008. are its diagonal elements, that multiplying a matrix on the left
  1009. by an orthogonal matrix, `Q`, and on the right by `Q.T` (the transpose
  1010. of `Q`), preserves the eigenvalues of the "middle" matrix. In other words,
  1011. if `Q` is orthogonal, then ``Q * A * Q.T`` has the same eigenvalues as
  1012. ``A``:
  1013. >>> import numpy as np
  1014. >>> from numpy import linalg as LA
  1015. >>> x = np.random.random()
  1016. >>> Q = np.array([[np.cos(x), -np.sin(x)], [np.sin(x), np.cos(x)]])
  1017. >>> LA.norm(Q[0, :]), LA.norm(Q[1, :]), np.dot(Q[0, :],Q[1, :])
  1018. (1.0, 1.0, 0.0)
  1019. Now multiply a diagonal matrix by ``Q`` on one side and
  1020. by ``Q.T`` on the other:
  1021. >>> D = np.diag((-1,1))
  1022. >>> LA.eigvals(D)
  1023. array([-1., 1.])
  1024. >>> A = np.dot(Q, D)
  1025. >>> A = np.dot(A, Q.T)
  1026. >>> LA.eigvals(A)
  1027. array([ 1., -1.]) # random
  1028. """
  1029. a, wrap = _makearray(a)
  1030. _assert_stacked_square(a)
  1031. _assert_finite(a)
  1032. t, result_t = _commonType(a)
  1033. signature = 'D->D' if isComplexType(t) else 'd->D'
  1034. with errstate(call=_raise_linalgerror_eigenvalues_nonconvergence,
  1035. invalid='call', over='ignore', divide='ignore',
  1036. under='ignore'):
  1037. w = _umath_linalg.eigvals(a, signature=signature)
  1038. if not isComplexType(t):
  1039. if all(w.imag == 0):
  1040. w = w.real
  1041. result_t = _realType(result_t)
  1042. else:
  1043. result_t = _complexType(result_t)
  1044. return w.astype(result_t, copy=False)
  1045. def _eigvalsh_dispatcher(a, UPLO=None):
  1046. return (a,)
  1047. @array_function_dispatch(_eigvalsh_dispatcher)
  1048. def eigvalsh(a, UPLO='L'):
  1049. """
  1050. Compute the eigenvalues of a complex Hermitian or real symmetric matrix.
  1051. Main difference from eigh: the eigenvectors are not computed.
  1052. Parameters
  1053. ----------
  1054. a : (..., M, M) array_like
  1055. A complex- or real-valued matrix whose eigenvalues are to be
  1056. computed.
  1057. UPLO : {'L', 'U'}, optional
  1058. Specifies whether the calculation is done with the lower triangular
  1059. part of `a` ('L', default) or the upper triangular part ('U').
  1060. Irrespective of this value only the real parts of the diagonal will
  1061. be considered in the computation to preserve the notion of a Hermitian
  1062. matrix. It therefore follows that the imaginary part of the diagonal
  1063. will always be treated as zero.
  1064. Returns
  1065. -------
  1066. w : (..., M,) ndarray
  1067. The eigenvalues in ascending order, each repeated according to
  1068. its multiplicity.
  1069. Raises
  1070. ------
  1071. LinAlgError
  1072. If the eigenvalue computation does not converge.
  1073. See Also
  1074. --------
  1075. eigh : eigenvalues and eigenvectors of real symmetric or complex Hermitian
  1076. (conjugate symmetric) arrays.
  1077. eigvals : eigenvalues of general real or complex arrays.
  1078. eig : eigenvalues and right eigenvectors of general real or complex
  1079. arrays.
  1080. scipy.linalg.eigvalsh : Similar function in SciPy.
  1081. Notes
  1082. -----
  1083. Broadcasting rules apply, see the `numpy.linalg` documentation for
  1084. details.
  1085. The eigenvalues are computed using LAPACK routines ``_syevd``, ``_heevd``.
  1086. Examples
  1087. --------
  1088. >>> import numpy as np
  1089. >>> from numpy import linalg as LA
  1090. >>> a = np.array([[1, -2j], [2j, 5]])
  1091. >>> LA.eigvalsh(a)
  1092. array([ 0.17157288, 5.82842712]) # may vary
  1093. >>> # demonstrate the treatment of the imaginary part of the diagonal
  1094. >>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]])
  1095. >>> a
  1096. array([[5.+2.j, 9.-2.j],
  1097. [0.+2.j, 2.-1.j]])
  1098. >>> # with UPLO='L' this is numerically equivalent to using LA.eigvals()
  1099. >>> # with:
  1100. >>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]])
  1101. >>> b
  1102. array([[5.+0.j, 0.-2.j],
  1103. [0.+2.j, 2.+0.j]])
  1104. >>> wa = LA.eigvalsh(a)
  1105. >>> wb = LA.eigvals(b)
  1106. >>> wa
  1107. array([1., 6.])
  1108. >>> wb
  1109. array([6.+0.j, 1.+0.j])
  1110. """
  1111. UPLO = UPLO.upper()
  1112. if UPLO not in ('L', 'U'):
  1113. raise ValueError("UPLO argument must be 'L' or 'U'")
  1114. if UPLO == 'L':
  1115. gufunc = _umath_linalg.eigvalsh_lo
  1116. else:
  1117. gufunc = _umath_linalg.eigvalsh_up
  1118. a, wrap = _makearray(a)
  1119. _assert_stacked_square(a)
  1120. t, result_t = _commonType(a)
  1121. signature = 'D->d' if isComplexType(t) else 'd->d'
  1122. with errstate(call=_raise_linalgerror_eigenvalues_nonconvergence,
  1123. invalid='call', over='ignore', divide='ignore',
  1124. under='ignore'):
  1125. w = gufunc(a, signature=signature)
  1126. return w.astype(_realType(result_t), copy=False)
  1127. # Eigenvectors
  1128. @array_function_dispatch(_unary_dispatcher)
  1129. def eig(a):
  1130. """
  1131. Compute the eigenvalues and right eigenvectors of a square array.
  1132. Parameters
  1133. ----------
  1134. a : (..., M, M) array
  1135. Matrices for which the eigenvalues and right eigenvectors will
  1136. be computed
  1137. Returns
  1138. -------
  1139. A namedtuple with the following attributes:
  1140. eigenvalues : (..., M) array
  1141. The eigenvalues, each repeated according to its multiplicity.
  1142. The eigenvalues are not necessarily ordered. The resulting
  1143. array will be of complex type, unless the imaginary part is
  1144. zero in which case it will be cast to a real type. When `a`
  1145. is real the resulting eigenvalues will be real (0 imaginary
  1146. part) or occur in conjugate pairs
  1147. eigenvectors : (..., M, M) array
  1148. The normalized (unit "length") eigenvectors, such that the
  1149. column ``eigenvectors[:,i]`` is the eigenvector corresponding to the
  1150. eigenvalue ``eigenvalues[i]``.
  1151. Raises
  1152. ------
  1153. LinAlgError
  1154. If the eigenvalue computation does not converge.
  1155. See Also
  1156. --------
  1157. eigvals : eigenvalues of a non-symmetric array.
  1158. eigh : eigenvalues and eigenvectors of a real symmetric or complex
  1159. Hermitian (conjugate symmetric) array.
  1160. eigvalsh : eigenvalues of a real symmetric or complex Hermitian
  1161. (conjugate symmetric) array.
  1162. scipy.linalg.eig : Similar function in SciPy that also solves the
  1163. generalized eigenvalue problem.
  1164. scipy.linalg.schur : Best choice for unitary and other non-Hermitian
  1165. normal matrices.
  1166. Notes
  1167. -----
  1168. Broadcasting rules apply, see the `numpy.linalg` documentation for
  1169. details.
  1170. This is implemented using the ``_geev`` LAPACK routines which compute
  1171. the eigenvalues and eigenvectors of general square arrays.
  1172. The number `w` is an eigenvalue of `a` if there exists a vector `v` such
  1173. that ``a @ v = w * v``. Thus, the arrays `a`, `eigenvalues`, and
  1174. `eigenvectors` satisfy the equations ``a @ eigenvectors[:,i] =
  1175. eigenvalues[i] * eigenvectors[:,i]`` for :math:`i \\in \\{0,...,M-1\\}`.
  1176. The array `eigenvectors` may not be of maximum rank, that is, some of the
  1177. columns may be linearly dependent, although round-off error may obscure
  1178. that fact. If the eigenvalues are all different, then theoretically the
  1179. eigenvectors are linearly independent and `a` can be diagonalized by a
  1180. similarity transformation using `eigenvectors`, i.e, ``inv(eigenvectors) @
  1181. a @ eigenvectors`` is diagonal.
  1182. For non-Hermitian normal matrices the SciPy function `scipy.linalg.schur`
  1183. is preferred because the matrix `eigenvectors` is guaranteed to be
  1184. unitary, which is not the case when using `eig`. The Schur factorization
  1185. produces an upper triangular matrix rather than a diagonal matrix, but for
  1186. normal matrices only the diagonal of the upper triangular matrix is
  1187. needed, the rest is roundoff error.
  1188. Finally, it is emphasized that `eigenvectors` consists of the *right* (as
  1189. in right-hand side) eigenvectors of `a`. A vector `y` satisfying ``y.T @ a
  1190. = z * y.T`` for some number `z` is called a *left* eigenvector of `a`,
  1191. and, in general, the left and right eigenvectors of a matrix are not
  1192. necessarily the (perhaps conjugate) transposes of each other.
  1193. References
  1194. ----------
  1195. G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, FL,
  1196. Academic Press, Inc., 1980, Various pp.
  1197. Examples
  1198. --------
  1199. >>> import numpy as np
  1200. >>> from numpy import linalg as LA
  1201. (Almost) trivial example with real eigenvalues and eigenvectors.
  1202. >>> eigenvalues, eigenvectors = LA.eig(np.diag((1, 2, 3)))
  1203. >>> eigenvalues
  1204. array([1., 2., 3.])
  1205. >>> eigenvectors
  1206. array([[1., 0., 0.],
  1207. [0., 1., 0.],
  1208. [0., 0., 1.]])
  1209. Real matrix possessing complex eigenvalues and eigenvectors;
  1210. note that the eigenvalues are complex conjugates of each other.
  1211. >>> eigenvalues, eigenvectors = LA.eig(np.array([[1, -1], [1, 1]]))
  1212. >>> eigenvalues
  1213. array([1.+1.j, 1.-1.j])
  1214. >>> eigenvectors
  1215. array([[0.70710678+0.j , 0.70710678-0.j ],
  1216. [0. -0.70710678j, 0. +0.70710678j]])
  1217. Complex-valued matrix with real eigenvalues (but complex-valued
  1218. eigenvectors); note that ``a.conj().T == a``, i.e., `a` is Hermitian.
  1219. >>> a = np.array([[1, 1j], [-1j, 1]])
  1220. >>> eigenvalues, eigenvectors = LA.eig(a)
  1221. >>> eigenvalues
  1222. array([2.+0.j, 0.+0.j])
  1223. >>> eigenvectors
  1224. array([[ 0. +0.70710678j, 0.70710678+0.j ], # may vary
  1225. [ 0.70710678+0.j , -0. +0.70710678j]])
  1226. Be careful about round-off error!
  1227. >>> a = np.array([[1 + 1e-9, 0], [0, 1 - 1e-9]])
  1228. >>> # Theor. eigenvalues are 1 +/- 1e-9
  1229. >>> eigenvalues, eigenvectors = LA.eig(a)
  1230. >>> eigenvalues
  1231. array([1., 1.])
  1232. >>> eigenvectors
  1233. array([[1., 0.],
  1234. [0., 1.]])
  1235. """
  1236. a, wrap = _makearray(a)
  1237. _assert_stacked_square(a)
  1238. _assert_finite(a)
  1239. t, result_t = _commonType(a)
  1240. signature = 'D->DD' if isComplexType(t) else 'd->DD'
  1241. with errstate(call=_raise_linalgerror_eigenvalues_nonconvergence,
  1242. invalid='call', over='ignore', divide='ignore',
  1243. under='ignore'):
  1244. w, vt = _umath_linalg.eig(a, signature=signature)
  1245. if not isComplexType(t) and all(w.imag == 0.0):
  1246. w = w.real
  1247. vt = vt.real
  1248. result_t = _realType(result_t)
  1249. else:
  1250. result_t = _complexType(result_t)
  1251. vt = vt.astype(result_t, copy=False)
  1252. return EigResult(w.astype(result_t, copy=False), wrap(vt))
  1253. @array_function_dispatch(_eigvalsh_dispatcher)
  1254. def eigh(a, UPLO='L'):
  1255. """
  1256. Return the eigenvalues and eigenvectors of a complex Hermitian
  1257. (conjugate symmetric) or a real symmetric matrix.
  1258. Returns two objects, a 1-D array containing the eigenvalues of `a`, and
  1259. a 2-D square array or matrix (depending on the input type) of the
  1260. corresponding eigenvectors (in columns).
  1261. Parameters
  1262. ----------
  1263. a : (..., M, M) array
  1264. Hermitian or real symmetric matrices whose eigenvalues and
  1265. eigenvectors are to be computed.
  1266. UPLO : {'L', 'U'}, optional
  1267. Specifies whether the calculation is done with the lower triangular
  1268. part of `a` ('L', default) or the upper triangular part ('U').
  1269. Irrespective of this value only the real parts of the diagonal will
  1270. be considered in the computation to preserve the notion of a Hermitian
  1271. matrix. It therefore follows that the imaginary part of the diagonal
  1272. will always be treated as zero.
  1273. Returns
  1274. -------
  1275. A namedtuple with the following attributes:
  1276. eigenvalues : (..., M) ndarray
  1277. The eigenvalues in ascending order, each repeated according to
  1278. its multiplicity.
  1279. eigenvectors : {(..., M, M) ndarray, (..., M, M) matrix}
  1280. The column ``eigenvectors[:, i]`` is the normalized eigenvector
  1281. corresponding to the eigenvalue ``eigenvalues[i]``. Will return a
  1282. matrix object if `a` is a matrix object.
  1283. Raises
  1284. ------
  1285. LinAlgError
  1286. If the eigenvalue computation does not converge.
  1287. See Also
  1288. --------
  1289. eigvalsh : eigenvalues of real symmetric or complex Hermitian
  1290. (conjugate symmetric) arrays.
  1291. eig : eigenvalues and right eigenvectors for non-symmetric arrays.
  1292. eigvals : eigenvalues of non-symmetric arrays.
  1293. scipy.linalg.eigh : Similar function in SciPy (but also solves the
  1294. generalized eigenvalue problem).
  1295. Notes
  1296. -----
  1297. Broadcasting rules apply, see the `numpy.linalg` documentation for
  1298. details.
  1299. The eigenvalues/eigenvectors are computed using LAPACK routines ``_syevd``,
  1300. ``_heevd``.
  1301. The eigenvalues of real symmetric or complex Hermitian matrices are always
  1302. real. [1]_ The array `eigenvalues` of (column) eigenvectors is unitary and
  1303. `a`, `eigenvalues`, and `eigenvectors` satisfy the equations ``dot(a,
  1304. eigenvectors[:, i]) = eigenvalues[i] * eigenvectors[:, i]``.
  1305. References
  1306. ----------
  1307. .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
  1308. FL, Academic Press, Inc., 1980, pg. 222.
  1309. Examples
  1310. --------
  1311. >>> import numpy as np
  1312. >>> from numpy import linalg as LA
  1313. >>> a = np.array([[1, -2j], [2j, 5]])
  1314. >>> a
  1315. array([[ 1.+0.j, -0.-2.j],
  1316. [ 0.+2.j, 5.+0.j]])
  1317. >>> eigenvalues, eigenvectors = LA.eigh(a)
  1318. >>> eigenvalues
  1319. array([0.17157288, 5.82842712])
  1320. >>> eigenvectors
  1321. array([[-0.92387953+0.j , -0.38268343+0.j ], # may vary
  1322. [ 0. +0.38268343j, 0. -0.92387953j]])
  1323. >>> (np.dot(a, eigenvectors[:, 0]) -
  1324. ... eigenvalues[0] * eigenvectors[:, 0]) # verify 1st eigenval/vec pair
  1325. array([5.55111512e-17+0.0000000e+00j, 0.00000000e+00+1.2490009e-16j])
  1326. >>> (np.dot(a, eigenvectors[:, 1]) -
  1327. ... eigenvalues[1] * eigenvectors[:, 1]) # verify 2nd eigenval/vec pair
  1328. array([0.+0.j, 0.+0.j])
  1329. >>> A = np.matrix(a) # what happens if input is a matrix object
  1330. >>> A
  1331. matrix([[ 1.+0.j, -0.-2.j],
  1332. [ 0.+2.j, 5.+0.j]])
  1333. >>> eigenvalues, eigenvectors = LA.eigh(A)
  1334. >>> eigenvalues
  1335. array([0.17157288, 5.82842712])
  1336. >>> eigenvectors
  1337. matrix([[-0.92387953+0.j , -0.38268343+0.j ], # may vary
  1338. [ 0. +0.38268343j, 0. -0.92387953j]])
  1339. >>> # demonstrate the treatment of the imaginary part of the diagonal
  1340. >>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]])
  1341. >>> a
  1342. array([[5.+2.j, 9.-2.j],
  1343. [0.+2.j, 2.-1.j]])
  1344. >>> # with UPLO='L' this is numerically equivalent to using LA.eig() with:
  1345. >>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]])
  1346. >>> b
  1347. array([[5.+0.j, 0.-2.j],
  1348. [0.+2.j, 2.+0.j]])
  1349. >>> wa, va = LA.eigh(a)
  1350. >>> wb, vb = LA.eig(b)
  1351. >>> wa
  1352. array([1., 6.])
  1353. >>> wb
  1354. array([6.+0.j, 1.+0.j])
  1355. >>> va
  1356. array([[-0.4472136 +0.j , -0.89442719+0.j ], # may vary
  1357. [ 0. +0.89442719j, 0. -0.4472136j ]])
  1358. >>> vb
  1359. array([[ 0.89442719+0.j , -0. +0.4472136j],
  1360. [-0. +0.4472136j, 0.89442719+0.j ]])
  1361. """
  1362. UPLO = UPLO.upper()
  1363. if UPLO not in ('L', 'U'):
  1364. raise ValueError("UPLO argument must be 'L' or 'U'")
  1365. a, wrap = _makearray(a)
  1366. _assert_stacked_square(a)
  1367. t, result_t = _commonType(a)
  1368. if UPLO == 'L':
  1369. gufunc = _umath_linalg.eigh_lo
  1370. else:
  1371. gufunc = _umath_linalg.eigh_up
  1372. signature = 'D->dD' if isComplexType(t) else 'd->dd'
  1373. with errstate(call=_raise_linalgerror_eigenvalues_nonconvergence,
  1374. invalid='call', over='ignore', divide='ignore',
  1375. under='ignore'):
  1376. w, vt = gufunc(a, signature=signature)
  1377. w = w.astype(_realType(result_t), copy=False)
  1378. vt = vt.astype(result_t, copy=False)
  1379. return EighResult(w, wrap(vt))
  1380. # Singular value decomposition
  1381. def _svd_dispatcher(a, full_matrices=None, compute_uv=None, hermitian=None):
  1382. return (a,)
  1383. @array_function_dispatch(_svd_dispatcher)
  1384. def svd(a, full_matrices=True, compute_uv=True, hermitian=False):
  1385. """
  1386. Singular Value Decomposition.
  1387. When `a` is a 2D array, and ``full_matrices=False``, then it is
  1388. factorized as ``u @ np.diag(s) @ vh = (u * s) @ vh``, where
  1389. `u` and the Hermitian transpose of `vh` are 2D arrays with
  1390. orthonormal columns and `s` is a 1D array of `a`'s singular
  1391. values. When `a` is higher-dimensional, SVD is applied in
  1392. stacked mode as explained below.
  1393. Parameters
  1394. ----------
  1395. a : (..., M, N) array_like
  1396. A real or complex array with ``a.ndim >= 2``.
  1397. full_matrices : bool, optional
  1398. If True (default), `u` and `vh` have the shapes ``(..., M, M)`` and
  1399. ``(..., N, N)``, respectively. Otherwise, the shapes are
  1400. ``(..., M, K)`` and ``(..., K, N)``, respectively, where
  1401. ``K = min(M, N)``.
  1402. compute_uv : bool, optional
  1403. Whether or not to compute `u` and `vh` in addition to `s`. True
  1404. by default.
  1405. hermitian : bool, optional
  1406. If True, `a` is assumed to be Hermitian (symmetric if real-valued),
  1407. enabling a more efficient method for finding singular values.
  1408. Defaults to False.
  1409. Returns
  1410. -------
  1411. When `compute_uv` is True, the result is a namedtuple with the following
  1412. attribute names:
  1413. U : { (..., M, M), (..., M, K) } array
  1414. Unitary array(s). The first ``a.ndim - 2`` dimensions have the same
  1415. size as those of the input `a`. The size of the last two dimensions
  1416. depends on the value of `full_matrices`. Only returned when
  1417. `compute_uv` is True.
  1418. S : (..., K) array
  1419. Vector(s) with the singular values, within each vector sorted in
  1420. descending order. The first ``a.ndim - 2`` dimensions have the same
  1421. size as those of the input `a`.
  1422. Vh : { (..., N, N), (..., K, N) } array
  1423. Unitary array(s). The first ``a.ndim - 2`` dimensions have the same
  1424. size as those of the input `a`. The size of the last two dimensions
  1425. depends on the value of `full_matrices`. Only returned when
  1426. `compute_uv` is True.
  1427. Raises
  1428. ------
  1429. LinAlgError
  1430. If SVD computation does not converge.
  1431. See Also
  1432. --------
  1433. scipy.linalg.svd : Similar function in SciPy.
  1434. scipy.linalg.svdvals : Compute singular values of a matrix.
  1435. Notes
  1436. -----
  1437. The decomposition is performed using LAPACK routine ``_gesdd``.
  1438. SVD is usually described for the factorization of a 2D matrix :math:`A`.
  1439. The higher-dimensional case will be discussed below. In the 2D case, SVD is
  1440. written as :math:`A = U S V^H`, where :math:`A = a`, :math:`U= u`,
  1441. :math:`S= \\mathtt{np.diag}(s)` and :math:`V^H = vh`. The 1D array `s`
  1442. contains the singular values of `a` and `u` and `vh` are unitary. The rows
  1443. of `vh` are the eigenvectors of :math:`A^H A` and the columns of `u` are
  1444. the eigenvectors of :math:`A A^H`. In both cases the corresponding
  1445. (possibly non-zero) eigenvalues are given by ``s**2``.
  1446. If `a` has more than two dimensions, then broadcasting rules apply, as
  1447. explained in :ref:`routines.linalg-broadcasting`. This means that SVD is
  1448. working in "stacked" mode: it iterates over all indices of the first
  1449. ``a.ndim - 2`` dimensions and for each combination SVD is applied to the
  1450. last two indices. The matrix `a` can be reconstructed from the
  1451. decomposition with either ``(u * s[..., None, :]) @ vh`` or
  1452. ``u @ (s[..., None] * vh)``. (The ``@`` operator can be replaced by the
  1453. function ``np.matmul`` for python versions below 3.5.)
  1454. If `a` is a ``matrix`` object (as opposed to an ``ndarray``), then so are
  1455. all the return values.
  1456. Examples
  1457. --------
  1458. >>> import numpy as np
  1459. >>> rng = np.random.default_rng()
  1460. >>> a = rng.normal(size=(9, 6)) + 1j*rng.normal(size=(9, 6))
  1461. >>> b = rng.normal(size=(2, 7, 8, 3)) + 1j*rng.normal(size=(2, 7, 8, 3))
  1462. Reconstruction based on full SVD, 2D case:
  1463. >>> U, S, Vh = np.linalg.svd(a, full_matrices=True)
  1464. >>> U.shape, S.shape, Vh.shape
  1465. ((9, 9), (6,), (6, 6))
  1466. >>> np.allclose(a, np.dot(U[:, :6] * S, Vh))
  1467. True
  1468. >>> smat = np.zeros((9, 6), dtype=complex)
  1469. >>> smat[:6, :6] = np.diag(S)
  1470. >>> np.allclose(a, np.dot(U, np.dot(smat, Vh)))
  1471. True
  1472. Reconstruction based on reduced SVD, 2D case:
  1473. >>> U, S, Vh = np.linalg.svd(a, full_matrices=False)
  1474. >>> U.shape, S.shape, Vh.shape
  1475. ((9, 6), (6,), (6, 6))
  1476. >>> np.allclose(a, np.dot(U * S, Vh))
  1477. True
  1478. >>> smat = np.diag(S)
  1479. >>> np.allclose(a, np.dot(U, np.dot(smat, Vh)))
  1480. True
  1481. Reconstruction based on full SVD, 4D case:
  1482. >>> U, S, Vh = np.linalg.svd(b, full_matrices=True)
  1483. >>> U.shape, S.shape, Vh.shape
  1484. ((2, 7, 8, 8), (2, 7, 3), (2, 7, 3, 3))
  1485. >>> np.allclose(b, np.matmul(U[..., :3] * S[..., None, :], Vh))
  1486. True
  1487. >>> np.allclose(b, np.matmul(U[..., :3], S[..., None] * Vh))
  1488. True
  1489. Reconstruction based on reduced SVD, 4D case:
  1490. >>> U, S, Vh = np.linalg.svd(b, full_matrices=False)
  1491. >>> U.shape, S.shape, Vh.shape
  1492. ((2, 7, 8, 3), (2, 7, 3), (2, 7, 3, 3))
  1493. >>> np.allclose(b, np.matmul(U * S[..., None, :], Vh))
  1494. True
  1495. >>> np.allclose(b, np.matmul(U, S[..., None] * Vh))
  1496. True
  1497. """
  1498. import numpy as np
  1499. a, wrap = _makearray(a)
  1500. if hermitian:
  1501. # note: lapack svd returns eigenvalues with s ** 2 sorted descending,
  1502. # but eig returns s sorted ascending, so we re-order the eigenvalues
  1503. # and related arrays to have the correct order
  1504. if compute_uv:
  1505. s, u = eigh(a)
  1506. sgn = sign(s)
  1507. s = abs(s)
  1508. sidx = argsort(s)[..., ::-1]
  1509. sgn = np.take_along_axis(sgn, sidx, axis=-1)
  1510. s = np.take_along_axis(s, sidx, axis=-1)
  1511. u = np.take_along_axis(u, sidx[..., None, :], axis=-1)
  1512. # singular values are unsigned, move the sign into v
  1513. vt = transpose(u * sgn[..., None, :]).conjugate()
  1514. return SVDResult(wrap(u), s, wrap(vt))
  1515. else:
  1516. s = eigvalsh(a)
  1517. s = abs(s)
  1518. return sort(s)[..., ::-1]
  1519. _assert_stacked_2d(a)
  1520. t, result_t = _commonType(a)
  1521. m, n = a.shape[-2:]
  1522. if compute_uv:
  1523. if full_matrices:
  1524. gufunc = _umath_linalg.svd_f
  1525. else:
  1526. gufunc = _umath_linalg.svd_s
  1527. signature = 'D->DdD' if isComplexType(t) else 'd->ddd'
  1528. with errstate(call=_raise_linalgerror_svd_nonconvergence,
  1529. invalid='call', over='ignore', divide='ignore',
  1530. under='ignore'):
  1531. u, s, vh = gufunc(a, signature=signature)
  1532. u = u.astype(result_t, copy=False)
  1533. s = s.astype(_realType(result_t), copy=False)
  1534. vh = vh.astype(result_t, copy=False)
  1535. return SVDResult(wrap(u), s, wrap(vh))
  1536. else:
  1537. signature = 'D->d' if isComplexType(t) else 'd->d'
  1538. with errstate(call=_raise_linalgerror_svd_nonconvergence,
  1539. invalid='call', over='ignore', divide='ignore',
  1540. under='ignore'):
  1541. s = _umath_linalg.svd(a, signature=signature)
  1542. s = s.astype(_realType(result_t), copy=False)
  1543. return s
  1544. def _svdvals_dispatcher(x):
  1545. return (x,)
  1546. @array_function_dispatch(_svdvals_dispatcher)
  1547. def svdvals(x, /):
  1548. """
  1549. Returns the singular values of a matrix (or a stack of matrices) ``x``.
  1550. When x is a stack of matrices, the function will compute the singular
  1551. values for each matrix in the stack.
  1552. This function is Array API compatible.
  1553. Calling ``np.svdvals(x)`` to get singular values is the same as
  1554. ``np.svd(x, compute_uv=False, hermitian=False)``.
  1555. Parameters
  1556. ----------
  1557. x : (..., M, N) array_like
  1558. Input array having shape (..., M, N) and whose last two
  1559. dimensions form matrices on which to perform singular value
  1560. decomposition. Should have a floating-point data type.
  1561. Returns
  1562. -------
  1563. out : ndarray
  1564. An array with shape (..., K) that contains the vector(s)
  1565. of singular values of length K, where K = min(M, N).
  1566. See Also
  1567. --------
  1568. scipy.linalg.svdvals : Compute singular values of a matrix.
  1569. Examples
  1570. --------
  1571. >>> np.linalg.svdvals([[1, 2, 3, 4, 5],
  1572. ... [1, 4, 9, 16, 25],
  1573. ... [1, 8, 27, 64, 125]])
  1574. array([146.68862757, 5.57510612, 0.60393245])
  1575. Determine the rank of a matrix using singular values:
  1576. >>> s = np.linalg.svdvals([[1, 2, 3],
  1577. ... [2, 4, 6],
  1578. ... [-1, 1, -1]]); s
  1579. array([8.38434191e+00, 1.64402274e+00, 2.31534378e-16])
  1580. >>> np.count_nonzero(s > 1e-10) # Matrix of rank 2
  1581. 2
  1582. """
  1583. return svd(x, compute_uv=False, hermitian=False)
  1584. def _cond_dispatcher(x, p=None):
  1585. return (x,)
  1586. @array_function_dispatch(_cond_dispatcher)
  1587. def cond(x, p=None):
  1588. """
  1589. Compute the condition number of a matrix.
  1590. This function is capable of returning the condition number using
  1591. one of seven different norms, depending on the value of `p` (see
  1592. Parameters below).
  1593. Parameters
  1594. ----------
  1595. x : (..., M, N) array_like
  1596. The matrix whose condition number is sought.
  1597. p : {None, 1, -1, 2, -2, inf, -inf, 'fro'}, optional
  1598. Order of the norm used in the condition number computation:
  1599. ===== ============================
  1600. p norm for matrices
  1601. ===== ============================
  1602. None 2-norm, computed directly using the ``SVD``
  1603. 'fro' Frobenius norm
  1604. inf max(sum(abs(x), axis=1))
  1605. -inf min(sum(abs(x), axis=1))
  1606. 1 max(sum(abs(x), axis=0))
  1607. -1 min(sum(abs(x), axis=0))
  1608. 2 2-norm (largest sing. value)
  1609. -2 smallest singular value
  1610. ===== ============================
  1611. inf means the `numpy.inf` object, and the Frobenius norm is
  1612. the root-of-sum-of-squares norm.
  1613. Returns
  1614. -------
  1615. c : {float, inf}
  1616. The condition number of the matrix. May be infinite.
  1617. See Also
  1618. --------
  1619. numpy.linalg.norm
  1620. Notes
  1621. -----
  1622. The condition number of `x` is defined as the norm of `x` times the
  1623. norm of the inverse of `x` [1]_; the norm can be the usual L2-norm
  1624. (root-of-sum-of-squares) or one of a number of other matrix norms.
  1625. References
  1626. ----------
  1627. .. [1] G. Strang, *Linear Algebra and Its Applications*, Orlando, FL,
  1628. Academic Press, Inc., 1980, pg. 285.
  1629. Examples
  1630. --------
  1631. >>> import numpy as np
  1632. >>> from numpy import linalg as LA
  1633. >>> a = np.array([[1, 0, -1], [0, 1, 0], [1, 0, 1]])
  1634. >>> a
  1635. array([[ 1, 0, -1],
  1636. [ 0, 1, 0],
  1637. [ 1, 0, 1]])
  1638. >>> LA.cond(a)
  1639. 1.4142135623730951
  1640. >>> LA.cond(a, 'fro')
  1641. 3.1622776601683795
  1642. >>> LA.cond(a, np.inf)
  1643. 2.0
  1644. >>> LA.cond(a, -np.inf)
  1645. 1.0
  1646. >>> LA.cond(a, 1)
  1647. 2.0
  1648. >>> LA.cond(a, -1)
  1649. 1.0
  1650. >>> LA.cond(a, 2)
  1651. 1.4142135623730951
  1652. >>> LA.cond(a, -2)
  1653. 0.70710678118654746 # may vary
  1654. >>> (min(LA.svd(a, compute_uv=False)) *
  1655. ... min(LA.svd(LA.inv(a), compute_uv=False)))
  1656. 0.70710678118654746 # may vary
  1657. """
  1658. x = asarray(x) # in case we have a matrix
  1659. if _is_empty_2d(x):
  1660. raise LinAlgError("cond is not defined on empty arrays")
  1661. if p is None or p in {2, -2}:
  1662. s = svd(x, compute_uv=False)
  1663. with errstate(all='ignore'):
  1664. if p == -2:
  1665. r = s[..., -1] / s[..., 0]
  1666. else:
  1667. r = s[..., 0] / s[..., -1]
  1668. else:
  1669. # Call inv(x) ignoring errors. The result array will
  1670. # contain nans in the entries where inversion failed.
  1671. _assert_stacked_square(x)
  1672. t, result_t = _commonType(x)
  1673. signature = 'D->D' if isComplexType(t) else 'd->d'
  1674. with errstate(all='ignore'):
  1675. invx = _umath_linalg.inv(x, signature=signature)
  1676. r = norm(x, p, axis=(-2, -1)) * norm(invx, p, axis=(-2, -1))
  1677. r = r.astype(result_t, copy=False)
  1678. # Convert nans to infs unless the original array had nan entries
  1679. r = asarray(r)
  1680. nan_mask = isnan(r)
  1681. if nan_mask.any():
  1682. nan_mask &= ~isnan(x).any(axis=(-2, -1))
  1683. if r.ndim > 0:
  1684. r[nan_mask] = inf
  1685. elif nan_mask:
  1686. r[()] = inf
  1687. # Convention is to return scalars instead of 0d arrays
  1688. if r.ndim == 0:
  1689. r = r[()]
  1690. return r
  1691. def _matrix_rank_dispatcher(A, tol=None, hermitian=None, *, rtol=None):
  1692. return (A,)
  1693. @array_function_dispatch(_matrix_rank_dispatcher)
  1694. def matrix_rank(A, tol=None, hermitian=False, *, rtol=None):
  1695. """
  1696. Return matrix rank of array using SVD method
  1697. Rank of the array is the number of singular values of the array that are
  1698. greater than `tol`.
  1699. Parameters
  1700. ----------
  1701. A : {(M,), (..., M, N)} array_like
  1702. Input vector or stack of matrices.
  1703. tol : (...) array_like, float, optional
  1704. Threshold below which SVD values are considered zero. If `tol` is
  1705. None, and ``S`` is an array with singular values for `M`, and
  1706. ``eps`` is the epsilon value for datatype of ``S``, then `tol` is
  1707. set to ``S.max() * max(M, N) * eps``.
  1708. hermitian : bool, optional
  1709. If True, `A` is assumed to be Hermitian (symmetric if real-valued),
  1710. enabling a more efficient method for finding singular values.
  1711. Defaults to False.
  1712. rtol : (...) array_like, float, optional
  1713. Parameter for the relative tolerance component. Only ``tol`` or
  1714. ``rtol`` can be set at a time. Defaults to ``max(M, N) * eps``.
  1715. .. versionadded:: 2.0.0
  1716. Returns
  1717. -------
  1718. rank : (...) array_like
  1719. Rank of A.
  1720. Notes
  1721. -----
  1722. The default threshold to detect rank deficiency is a test on the magnitude
  1723. of the singular values of `A`. By default, we identify singular values
  1724. less than ``S.max() * max(M, N) * eps`` as indicating rank deficiency
  1725. (with the symbols defined above). This is the algorithm MATLAB uses [1].
  1726. It also appears in *Numerical recipes* in the discussion of SVD solutions
  1727. for linear least squares [2].
  1728. This default threshold is designed to detect rank deficiency accounting
  1729. for the numerical errors of the SVD computation. Imagine that there
  1730. is a column in `A` that is an exact (in floating point) linear combination
  1731. of other columns in `A`. Computing the SVD on `A` will not produce
  1732. a singular value exactly equal to 0 in general: any difference of
  1733. the smallest SVD value from 0 will be caused by numerical imprecision
  1734. in the calculation of the SVD. Our threshold for small SVD values takes
  1735. this numerical imprecision into account, and the default threshold will
  1736. detect such numerical rank deficiency. The threshold may declare a matrix
  1737. `A` rank deficient even if the linear combination of some columns of `A`
  1738. is not exactly equal to another column of `A` but only numerically very
  1739. close to another column of `A`.
  1740. We chose our default threshold because it is in wide use. Other thresholds
  1741. are possible. For example, elsewhere in the 2007 edition of *Numerical
  1742. recipes* there is an alternative threshold of ``S.max() *
  1743. np.finfo(A.dtype).eps / 2. * np.sqrt(m + n + 1.)``. The authors describe
  1744. this threshold as being based on "expected roundoff error" (p 71).
  1745. The thresholds above deal with floating point roundoff error in the
  1746. calculation of the SVD. However, you may have more information about
  1747. the sources of error in `A` that would make you consider other tolerance
  1748. values to detect *effective* rank deficiency. The most useful measure
  1749. of the tolerance depends on the operations you intend to use on your
  1750. matrix. For example, if your data come from uncertain measurements with
  1751. uncertainties greater than floating point epsilon, choosing a tolerance
  1752. near that uncertainty may be preferable. The tolerance may be absolute
  1753. if the uncertainties are absolute rather than relative.
  1754. References
  1755. ----------
  1756. .. [1] MATLAB reference documentation, "Rank"
  1757. https://www.mathworks.com/help/techdoc/ref/rank.html
  1758. .. [2] W. H. Press, S. A. Teukolsky, W. T. Vetterling and B. P. Flannery,
  1759. "Numerical Recipes (3rd edition)", Cambridge University Press, 2007,
  1760. page 795.
  1761. Examples
  1762. --------
  1763. >>> import numpy as np
  1764. >>> from numpy.linalg import matrix_rank
  1765. >>> matrix_rank(np.eye(4)) # Full rank matrix
  1766. 4
  1767. >>> I=np.eye(4); I[-1,-1] = 0. # rank deficient matrix
  1768. >>> matrix_rank(I)
  1769. 3
  1770. >>> matrix_rank(np.ones((4,))) # 1 dimension - rank 1 unless all 0
  1771. 1
  1772. >>> matrix_rank(np.zeros((4,)))
  1773. 0
  1774. """
  1775. if rtol is not None and tol is not None:
  1776. raise ValueError("`tol` and `rtol` can't be both set.")
  1777. A = asarray(A)
  1778. if A.ndim < 2:
  1779. return int(not all(A == 0))
  1780. S = svd(A, compute_uv=False, hermitian=hermitian)
  1781. if tol is None:
  1782. if rtol is None:
  1783. rtol = max(A.shape[-2:]) * finfo(S.dtype).eps
  1784. else:
  1785. rtol = asarray(rtol)[..., newaxis]
  1786. tol = S.max(axis=-1, keepdims=True) * rtol
  1787. else:
  1788. tol = asarray(tol)[..., newaxis]
  1789. return count_nonzero(S > tol, axis=-1)
  1790. # Generalized inverse
  1791. def _pinv_dispatcher(a, rcond=None, hermitian=None, *, rtol=None):
  1792. return (a,)
  1793. @array_function_dispatch(_pinv_dispatcher)
  1794. def pinv(a, rcond=None, hermitian=False, *, rtol=_NoValue):
  1795. """
  1796. Compute the (Moore-Penrose) pseudo-inverse of a matrix.
  1797. Calculate the generalized inverse of a matrix using its
  1798. singular-value decomposition (SVD) and including all
  1799. *large* singular values.
  1800. Parameters
  1801. ----------
  1802. a : (..., M, N) array_like
  1803. Matrix or stack of matrices to be pseudo-inverted.
  1804. rcond : (...) array_like of float, optional
  1805. Cutoff for small singular values.
  1806. Singular values less than or equal to
  1807. ``rcond * largest_singular_value`` are set to zero.
  1808. Broadcasts against the stack of matrices. Default: ``1e-15``.
  1809. hermitian : bool, optional
  1810. If True, `a` is assumed to be Hermitian (symmetric if real-valued),
  1811. enabling a more efficient method for finding singular values.
  1812. Defaults to False.
  1813. rtol : (...) array_like of float, optional
  1814. Same as `rcond`, but it's an Array API compatible parameter name.
  1815. Only `rcond` or `rtol` can be set at a time. If none of them are
  1816. provided then NumPy's ``1e-15`` default is used. If ``rtol=None``
  1817. is passed then the API standard default is used.
  1818. .. versionadded:: 2.0.0
  1819. Returns
  1820. -------
  1821. B : (..., N, M) ndarray
  1822. The pseudo-inverse of `a`. If `a` is a `matrix` instance, then so
  1823. is `B`.
  1824. Raises
  1825. ------
  1826. LinAlgError
  1827. If the SVD computation does not converge.
  1828. See Also
  1829. --------
  1830. scipy.linalg.pinv : Similar function in SciPy.
  1831. scipy.linalg.pinvh : Compute the (Moore-Penrose) pseudo-inverse of a
  1832. Hermitian matrix.
  1833. Notes
  1834. -----
  1835. The pseudo-inverse of a matrix A, denoted :math:`A^+`, is
  1836. defined as: "the matrix that 'solves' [the least-squares problem]
  1837. :math:`Ax = b`," i.e., if :math:`\\bar{x}` is said solution, then
  1838. :math:`A^+` is that matrix such that :math:`\\bar{x} = A^+b`.
  1839. It can be shown that if :math:`Q_1 \\Sigma Q_2^T = A` is the singular
  1840. value decomposition of A, then
  1841. :math:`A^+ = Q_2 \\Sigma^+ Q_1^T`, where :math:`Q_{1,2}` are
  1842. orthogonal matrices, :math:`\\Sigma` is a diagonal matrix consisting
  1843. of A's so-called singular values, (followed, typically, by
  1844. zeros), and then :math:`\\Sigma^+` is simply the diagonal matrix
  1845. consisting of the reciprocals of A's singular values
  1846. (again, followed by zeros). [1]_
  1847. References
  1848. ----------
  1849. .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
  1850. FL, Academic Press, Inc., 1980, pp. 139-142.
  1851. Examples
  1852. --------
  1853. The following example checks that ``a * a+ * a == a`` and
  1854. ``a+ * a * a+ == a+``:
  1855. >>> import numpy as np
  1856. >>> rng = np.random.default_rng()
  1857. >>> a = rng.normal(size=(9, 6))
  1858. >>> B = np.linalg.pinv(a)
  1859. >>> np.allclose(a, np.dot(a, np.dot(B, a)))
  1860. True
  1861. >>> np.allclose(B, np.dot(B, np.dot(a, B)))
  1862. True
  1863. """
  1864. a, wrap = _makearray(a)
  1865. if rcond is None:
  1866. if rtol is _NoValue:
  1867. rcond = 1e-15
  1868. elif rtol is None:
  1869. rcond = max(a.shape[-2:]) * finfo(a.dtype).eps
  1870. else:
  1871. rcond = rtol
  1872. elif rtol is not _NoValue:
  1873. raise ValueError("`rtol` and `rcond` can't be both set.")
  1874. else:
  1875. # NOTE: Deprecate `rcond` in a few versions.
  1876. pass
  1877. rcond = asarray(rcond)
  1878. if _is_empty_2d(a):
  1879. m, n = a.shape[-2:]
  1880. res = empty(a.shape[:-2] + (n, m), dtype=a.dtype)
  1881. return wrap(res)
  1882. a = a.conjugate()
  1883. u, s, vt = svd(a, full_matrices=False, hermitian=hermitian)
  1884. # discard small singular values
  1885. cutoff = rcond[..., newaxis] * amax(s, axis=-1, keepdims=True)
  1886. large = s > cutoff
  1887. s = divide(1, s, where=large, out=s)
  1888. s[~large] = 0
  1889. res = matmul(transpose(vt), multiply(s[..., newaxis], transpose(u)))
  1890. return wrap(res)
  1891. # Determinant
  1892. @array_function_dispatch(_unary_dispatcher)
  1893. def slogdet(a):
  1894. """
  1895. Compute the sign and (natural) logarithm of the determinant of an array.
  1896. If an array has a very small or very large determinant, then a call to
  1897. `det` may overflow or underflow. This routine is more robust against such
  1898. issues, because it computes the logarithm of the determinant rather than
  1899. the determinant itself.
  1900. Parameters
  1901. ----------
  1902. a : (..., M, M) array_like
  1903. Input array, has to be a square 2-D array.
  1904. Returns
  1905. -------
  1906. A namedtuple with the following attributes:
  1907. sign : (...) array_like
  1908. A number representing the sign of the determinant. For a real matrix,
  1909. this is 1, 0, or -1. For a complex matrix, this is a complex number
  1910. with absolute value 1 (i.e., it is on the unit circle), or else 0.
  1911. logabsdet : (...) array_like
  1912. The natural log of the absolute value of the determinant.
  1913. If the determinant is zero, then `sign` will be 0 and `logabsdet`
  1914. will be -inf. In all cases, the determinant is equal to
  1915. ``sign * np.exp(logabsdet)``.
  1916. See Also
  1917. --------
  1918. det
  1919. Notes
  1920. -----
  1921. Broadcasting rules apply, see the `numpy.linalg` documentation for
  1922. details.
  1923. The determinant is computed via LU factorization using the LAPACK
  1924. routine ``z/dgetrf``.
  1925. Examples
  1926. --------
  1927. The determinant of a 2-D array ``[[a, b], [c, d]]`` is ``ad - bc``:
  1928. >>> import numpy as np
  1929. >>> a = np.array([[1, 2], [3, 4]])
  1930. >>> (sign, logabsdet) = np.linalg.slogdet(a)
  1931. >>> (sign, logabsdet)
  1932. (-1, 0.69314718055994529) # may vary
  1933. >>> sign * np.exp(logabsdet)
  1934. -2.0
  1935. Computing log-determinants for a stack of matrices:
  1936. >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ])
  1937. >>> a.shape
  1938. (3, 2, 2)
  1939. >>> sign, logabsdet = np.linalg.slogdet(a)
  1940. >>> (sign, logabsdet)
  1941. (array([-1., -1., -1.]), array([ 0.69314718, 1.09861229, 2.07944154]))
  1942. >>> sign * np.exp(logabsdet)
  1943. array([-2., -3., -8.])
  1944. This routine succeeds where ordinary `det` does not:
  1945. >>> np.linalg.det(np.eye(500) * 0.1)
  1946. 0.0
  1947. >>> np.linalg.slogdet(np.eye(500) * 0.1)
  1948. (1, -1151.2925464970228)
  1949. """
  1950. a = asarray(a)
  1951. _assert_stacked_square(a)
  1952. t, result_t = _commonType(a)
  1953. real_t = _realType(result_t)
  1954. signature = 'D->Dd' if isComplexType(t) else 'd->dd'
  1955. sign, logdet = _umath_linalg.slogdet(a, signature=signature)
  1956. sign = sign.astype(result_t, copy=False)
  1957. logdet = logdet.astype(real_t, copy=False)
  1958. return SlogdetResult(sign, logdet)
  1959. @array_function_dispatch(_unary_dispatcher)
  1960. def det(a):
  1961. """
  1962. Compute the determinant of an array.
  1963. Parameters
  1964. ----------
  1965. a : (..., M, M) array_like
  1966. Input array to compute determinants for.
  1967. Returns
  1968. -------
  1969. det : (...) array_like
  1970. Determinant of `a`.
  1971. See Also
  1972. --------
  1973. slogdet : Another way to represent the determinant, more suitable
  1974. for large matrices where underflow/overflow may occur.
  1975. scipy.linalg.det : Similar function in SciPy.
  1976. Notes
  1977. -----
  1978. Broadcasting rules apply, see the `numpy.linalg` documentation for
  1979. details.
  1980. The determinant is computed via LU factorization using the LAPACK
  1981. routine ``z/dgetrf``.
  1982. Examples
  1983. --------
  1984. The determinant of a 2-D array [[a, b], [c, d]] is ad - bc:
  1985. >>> import numpy as np
  1986. >>> a = np.array([[1, 2], [3, 4]])
  1987. >>> np.linalg.det(a)
  1988. -2.0 # may vary
  1989. Computing determinants for a stack of matrices:
  1990. >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ])
  1991. >>> a.shape
  1992. (3, 2, 2)
  1993. >>> np.linalg.det(a)
  1994. array([-2., -3., -8.])
  1995. """
  1996. a = asarray(a)
  1997. _assert_stacked_square(a)
  1998. t, result_t = _commonType(a)
  1999. signature = 'D->D' if isComplexType(t) else 'd->d'
  2000. r = _umath_linalg.det(a, signature=signature)
  2001. r = r.astype(result_t, copy=False)
  2002. return r
  2003. # Linear Least Squares
  2004. def _lstsq_dispatcher(a, b, rcond=None):
  2005. return (a, b)
  2006. @array_function_dispatch(_lstsq_dispatcher)
  2007. def lstsq(a, b, rcond=None):
  2008. r"""
  2009. Return the least-squares solution to a linear matrix equation.
  2010. Computes the vector `x` that approximately solves the equation
  2011. ``a @ x = b``. The equation may be under-, well-, or over-determined
  2012. (i.e., the number of linearly independent rows of `a` can be less than,
  2013. equal to, or greater than its number of linearly independent columns).
  2014. If `a` is square and of full rank, then `x` (but for round-off error)
  2015. is the "exact" solution of the equation. Else, `x` minimizes the
  2016. Euclidean 2-norm :math:`||b - ax||`. If there are multiple minimizing
  2017. solutions, the one with the smallest 2-norm :math:`||x||` is returned.
  2018. Parameters
  2019. ----------
  2020. a : (M, N) array_like
  2021. "Coefficient" matrix.
  2022. b : {(M,), (M, K)} array_like
  2023. Ordinate or "dependent variable" values. If `b` is two-dimensional,
  2024. the least-squares solution is calculated for each of the `K` columns
  2025. of `b`.
  2026. rcond : float, optional
  2027. Cut-off ratio for small singular values of `a`.
  2028. For the purposes of rank determination, singular values are treated
  2029. as zero if they are smaller than `rcond` times the largest singular
  2030. value of `a`.
  2031. The default uses the machine precision times ``max(M, N)``. Passing
  2032. ``-1`` will use machine precision.
  2033. .. versionchanged:: 2.0
  2034. Previously, the default was ``-1``, but a warning was given that
  2035. this would change.
  2036. Returns
  2037. -------
  2038. x : {(N,), (N, K)} ndarray
  2039. Least-squares solution. If `b` is two-dimensional,
  2040. the solutions are in the `K` columns of `x`.
  2041. residuals : {(1,), (K,), (0,)} ndarray
  2042. Sums of squared residuals: Squared Euclidean 2-norm for each column in
  2043. ``b - a @ x``.
  2044. If the rank of `a` is < N or M <= N, this is an empty array.
  2045. If `b` is 1-dimensional, this is a (1,) shape array.
  2046. Otherwise the shape is (K,).
  2047. rank : int
  2048. Rank of matrix `a`.
  2049. s : (min(M, N),) ndarray
  2050. Singular values of `a`.
  2051. Raises
  2052. ------
  2053. LinAlgError
  2054. If computation does not converge.
  2055. See Also
  2056. --------
  2057. scipy.linalg.lstsq : Similar function in SciPy.
  2058. Notes
  2059. -----
  2060. If `b` is a matrix, then all array results are returned as matrices.
  2061. Examples
  2062. --------
  2063. Fit a line, ``y = mx + c``, through some noisy data-points:
  2064. >>> import numpy as np
  2065. >>> x = np.array([0, 1, 2, 3])
  2066. >>> y = np.array([-1, 0.2, 0.9, 2.1])
  2067. By examining the coefficients, we see that the line should have a
  2068. gradient of roughly 1 and cut the y-axis at, more or less, -1.
  2069. We can rewrite the line equation as ``y = Ap``, where ``A = [[x 1]]``
  2070. and ``p = [[m], [c]]``. Now use `lstsq` to solve for `p`:
  2071. >>> A = np.vstack([x, np.ones(len(x))]).T
  2072. >>> A
  2073. array([[ 0., 1.],
  2074. [ 1., 1.],
  2075. [ 2., 1.],
  2076. [ 3., 1.]])
  2077. >>> m, c = np.linalg.lstsq(A, y)[0]
  2078. >>> m, c
  2079. (1.0 -0.95) # may vary
  2080. Plot the data along with the fitted line:
  2081. >>> import matplotlib.pyplot as plt
  2082. >>> _ = plt.plot(x, y, 'o', label='Original data', markersize=10)
  2083. >>> _ = plt.plot(x, m*x + c, 'r', label='Fitted line')
  2084. >>> _ = plt.legend()
  2085. >>> plt.show()
  2086. """
  2087. a, _ = _makearray(a)
  2088. b, wrap = _makearray(b)
  2089. is_1d = b.ndim == 1
  2090. if is_1d:
  2091. b = b[:, newaxis]
  2092. _assert_2d(a, b)
  2093. m, n = a.shape[-2:]
  2094. m2, n_rhs = b.shape[-2:]
  2095. if m != m2:
  2096. raise LinAlgError('Incompatible dimensions')
  2097. t, result_t = _commonType(a, b)
  2098. result_real_t = _realType(result_t)
  2099. if rcond is None:
  2100. rcond = finfo(t).eps * max(n, m)
  2101. signature = 'DDd->Ddid' if isComplexType(t) else 'ddd->ddid'
  2102. if n_rhs == 0:
  2103. # lapack can't handle n_rhs = 0 - so allocate
  2104. # the array one larger in that axis
  2105. b = zeros(b.shape[:-2] + (m, n_rhs + 1), dtype=b.dtype)
  2106. with errstate(call=_raise_linalgerror_lstsq, invalid='call',
  2107. over='ignore', divide='ignore', under='ignore'):
  2108. x, resids, rank, s = _umath_linalg.lstsq(a, b, rcond,
  2109. signature=signature)
  2110. if m == 0:
  2111. x[...] = 0
  2112. if n_rhs == 0:
  2113. # remove the item we added
  2114. x = x[..., :n_rhs]
  2115. resids = resids[..., :n_rhs]
  2116. # remove the axis we added
  2117. if is_1d:
  2118. x = x.squeeze(axis=-1)
  2119. # we probably should squeeze resids too, but we can't
  2120. # without breaking compatibility.
  2121. # as documented
  2122. if rank != n or m <= n:
  2123. resids = array([], result_real_t)
  2124. # coerce output arrays
  2125. s = s.astype(result_real_t, copy=False)
  2126. resids = resids.astype(result_real_t, copy=False)
  2127. # Copying lets the memory in r_parts be freed
  2128. x = x.astype(result_t, copy=True)
  2129. return wrap(x), wrap(resids), rank, s
  2130. def _multi_svd_norm(x, row_axis, col_axis, op, initial=None):
  2131. """Compute a function of the singular values of the 2-D matrices in `x`.
  2132. This is a private utility function used by `numpy.linalg.norm()`.
  2133. Parameters
  2134. ----------
  2135. x : ndarray
  2136. row_axis, col_axis : int
  2137. The axes of `x` that hold the 2-D matrices.
  2138. op : callable
  2139. This should be either numpy.amin or `numpy.amax` or `numpy.sum`.
  2140. Returns
  2141. -------
  2142. result : float or ndarray
  2143. If `x` is 2-D, the return values is a float.
  2144. Otherwise, it is an array with ``x.ndim - 2`` dimensions.
  2145. The return values are either the minimum or maximum or sum of the
  2146. singular values of the matrices, depending on whether `op`
  2147. is `numpy.amin` or `numpy.amax` or `numpy.sum`.
  2148. """
  2149. y = moveaxis(x, (row_axis, col_axis), (-2, -1))
  2150. result = op(svd(y, compute_uv=False), axis=-1, initial=initial)
  2151. return result
  2152. def _norm_dispatcher(x, ord=None, axis=None, keepdims=None):
  2153. return (x,)
  2154. @array_function_dispatch(_norm_dispatcher)
  2155. def norm(x, ord=None, axis=None, keepdims=False):
  2156. """
  2157. Matrix or vector norm.
  2158. This function is able to return one of eight different matrix norms,
  2159. or one of an infinite number of vector norms (described below), depending
  2160. on the value of the ``ord`` parameter.
  2161. Parameters
  2162. ----------
  2163. x : array_like
  2164. Input array. If `axis` is None, `x` must be 1-D or 2-D, unless `ord`
  2165. is None. If both `axis` and `ord` are None, the 2-norm of
  2166. ``x.ravel`` will be returned.
  2167. ord : {int, float, inf, -inf, 'fro', 'nuc'}, optional
  2168. Order of the norm (see table under ``Notes`` for what values are
  2169. supported for matrices and vectors respectively). inf means numpy's
  2170. `inf` object. The default is None.
  2171. axis : {None, int, 2-tuple of ints}, optional.
  2172. If `axis` is an integer, it specifies the axis of `x` along which to
  2173. compute the vector norms. If `axis` is a 2-tuple, it specifies the
  2174. axes that hold 2-D matrices, and the matrix norms of these matrices
  2175. are computed. If `axis` is None then either a vector norm (when `x`
  2176. is 1-D) or a matrix norm (when `x` is 2-D) is returned. The default
  2177. is None.
  2178. keepdims : bool, optional
  2179. If this is set to True, the axes which are normed over are left in the
  2180. result as dimensions with size one. With this option the result will
  2181. broadcast correctly against the original `x`.
  2182. Returns
  2183. -------
  2184. n : float or ndarray
  2185. Norm of the matrix or vector(s).
  2186. See Also
  2187. --------
  2188. scipy.linalg.norm : Similar function in SciPy.
  2189. Notes
  2190. -----
  2191. For values of ``ord < 1``, the result is, strictly speaking, not a
  2192. mathematical 'norm', but it may still be useful for various numerical
  2193. purposes.
  2194. The following norms can be calculated:
  2195. ===== ============================ ==========================
  2196. ord norm for matrices norm for vectors
  2197. ===== ============================ ==========================
  2198. None Frobenius norm 2-norm
  2199. 'fro' Frobenius norm --
  2200. 'nuc' nuclear norm --
  2201. inf max(sum(abs(x), axis=1)) max(abs(x))
  2202. -inf min(sum(abs(x), axis=1)) min(abs(x))
  2203. 0 -- sum(x != 0)
  2204. 1 max(sum(abs(x), axis=0)) as below
  2205. -1 min(sum(abs(x), axis=0)) as below
  2206. 2 2-norm (largest sing. value) as below
  2207. -2 smallest singular value as below
  2208. other -- sum(abs(x)**ord)**(1./ord)
  2209. ===== ============================ ==========================
  2210. The Frobenius norm is given by [1]_:
  2211. :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}`
  2212. The nuclear norm is the sum of the singular values.
  2213. Both the Frobenius and nuclear norm orders are only defined for
  2214. matrices and raise a ValueError when ``x.ndim != 2``.
  2215. References
  2216. ----------
  2217. .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*,
  2218. Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15
  2219. Examples
  2220. --------
  2221. >>> import numpy as np
  2222. >>> from numpy import linalg as LA
  2223. >>> a = np.arange(9) - 4
  2224. >>> a
  2225. array([-4, -3, -2, ..., 2, 3, 4])
  2226. >>> b = a.reshape((3, 3))
  2227. >>> b
  2228. array([[-4, -3, -2],
  2229. [-1, 0, 1],
  2230. [ 2, 3, 4]])
  2231. >>> LA.norm(a)
  2232. 7.745966692414834
  2233. >>> LA.norm(b)
  2234. 7.745966692414834
  2235. >>> LA.norm(b, 'fro')
  2236. 7.745966692414834
  2237. >>> LA.norm(a, np.inf)
  2238. 4.0
  2239. >>> LA.norm(b, np.inf)
  2240. 9.0
  2241. >>> LA.norm(a, -np.inf)
  2242. 0.0
  2243. >>> LA.norm(b, -np.inf)
  2244. 2.0
  2245. >>> LA.norm(a, 1)
  2246. 20.0
  2247. >>> LA.norm(b, 1)
  2248. 7.0
  2249. >>> LA.norm(a, -1)
  2250. -4.6566128774142013e-010
  2251. >>> LA.norm(b, -1)
  2252. 6.0
  2253. >>> LA.norm(a, 2)
  2254. 7.745966692414834
  2255. >>> LA.norm(b, 2)
  2256. 7.3484692283495345
  2257. >>> LA.norm(a, -2)
  2258. 0.0
  2259. >>> LA.norm(b, -2)
  2260. 1.8570331885190563e-016 # may vary
  2261. >>> LA.norm(a, 3)
  2262. 5.8480354764257312 # may vary
  2263. >>> LA.norm(a, -3)
  2264. 0.0
  2265. Using the `axis` argument to compute vector norms:
  2266. >>> c = np.array([[ 1, 2, 3],
  2267. ... [-1, 1, 4]])
  2268. >>> LA.norm(c, axis=0)
  2269. array([ 1.41421356, 2.23606798, 5. ])
  2270. >>> LA.norm(c, axis=1)
  2271. array([ 3.74165739, 4.24264069])
  2272. >>> LA.norm(c, ord=1, axis=1)
  2273. array([ 6., 6.])
  2274. Using the `axis` argument to compute matrix norms:
  2275. >>> m = np.arange(8).reshape(2,2,2)
  2276. >>> LA.norm(m, axis=(1,2))
  2277. array([ 3.74165739, 11.22497216])
  2278. >>> LA.norm(m[0, :, :]), LA.norm(m[1, :, :])
  2279. (3.7416573867739413, 11.224972160321824)
  2280. """
  2281. x = asarray(x)
  2282. if not issubclass(x.dtype.type, (inexact, object_)):
  2283. x = x.astype(float)
  2284. # Immediately handle some default, simple, fast, and common cases.
  2285. if axis is None:
  2286. ndim = x.ndim
  2287. if (
  2288. (ord is None) or
  2289. (ord in ('f', 'fro') and ndim == 2) or
  2290. (ord == 2 and ndim == 1)
  2291. ):
  2292. x = x.ravel(order='K')
  2293. if isComplexType(x.dtype.type):
  2294. x_real = x.real
  2295. x_imag = x.imag
  2296. sqnorm = x_real.dot(x_real) + x_imag.dot(x_imag)
  2297. else:
  2298. sqnorm = x.dot(x)
  2299. ret = sqrt(sqnorm)
  2300. if keepdims:
  2301. ret = ret.reshape(ndim * [1])
  2302. return ret
  2303. # Normalize the `axis` argument to a tuple.
  2304. nd = x.ndim
  2305. if axis is None:
  2306. axis = tuple(range(nd))
  2307. elif not isinstance(axis, tuple):
  2308. try:
  2309. axis = int(axis)
  2310. except Exception as e:
  2311. raise TypeError(
  2312. "'axis' must be None, an integer or a tuple of integers"
  2313. ) from e
  2314. axis = (axis,)
  2315. if len(axis) == 1:
  2316. if ord == inf:
  2317. return abs(x).max(axis=axis, keepdims=keepdims, initial=0)
  2318. elif ord == -inf:
  2319. return abs(x).min(axis=axis, keepdims=keepdims)
  2320. elif ord == 0:
  2321. # Zero norm
  2322. return (
  2323. (x != 0)
  2324. .astype(x.real.dtype)
  2325. .sum(axis=axis, keepdims=keepdims)
  2326. )
  2327. elif ord == 1:
  2328. # special case for speedup
  2329. return add.reduce(abs(x), axis=axis, keepdims=keepdims)
  2330. elif ord is None or ord == 2:
  2331. # special case for speedup
  2332. s = (x.conj() * x).real
  2333. return sqrt(add.reduce(s, axis=axis, keepdims=keepdims))
  2334. # None of the str-type keywords for ord ('fro', 'nuc')
  2335. # are valid for vectors
  2336. elif isinstance(ord, str):
  2337. raise ValueError(f"Invalid norm order '{ord}' for vectors")
  2338. else:
  2339. absx = abs(x)
  2340. absx **= ord
  2341. ret = add.reduce(absx, axis=axis, keepdims=keepdims)
  2342. ret **= reciprocal(ord, dtype=ret.dtype)
  2343. return ret
  2344. elif len(axis) == 2:
  2345. row_axis, col_axis = axis
  2346. row_axis = normalize_axis_index(row_axis, nd)
  2347. col_axis = normalize_axis_index(col_axis, nd)
  2348. if row_axis == col_axis:
  2349. raise ValueError('Duplicate axes given.')
  2350. if ord == 2:
  2351. ret = _multi_svd_norm(x, row_axis, col_axis, amax, 0)
  2352. elif ord == -2:
  2353. ret = _multi_svd_norm(x, row_axis, col_axis, amin)
  2354. elif ord == 1:
  2355. if col_axis > row_axis:
  2356. col_axis -= 1
  2357. ret = add.reduce(abs(x), axis=row_axis).max(axis=col_axis, initial=0)
  2358. elif ord == inf:
  2359. if row_axis > col_axis:
  2360. row_axis -= 1
  2361. ret = add.reduce(abs(x), axis=col_axis).max(axis=row_axis, initial=0)
  2362. elif ord == -1:
  2363. if col_axis > row_axis:
  2364. col_axis -= 1
  2365. ret = add.reduce(abs(x), axis=row_axis).min(axis=col_axis)
  2366. elif ord == -inf:
  2367. if row_axis > col_axis:
  2368. row_axis -= 1
  2369. ret = add.reduce(abs(x), axis=col_axis).min(axis=row_axis)
  2370. elif ord in [None, 'fro', 'f']:
  2371. ret = sqrt(add.reduce((x.conj() * x).real, axis=axis))
  2372. elif ord == 'nuc':
  2373. ret = _multi_svd_norm(x, row_axis, col_axis, sum, 0)
  2374. else:
  2375. raise ValueError("Invalid norm order for matrices.")
  2376. if keepdims:
  2377. ret_shape = list(x.shape)
  2378. ret_shape[axis[0]] = 1
  2379. ret_shape[axis[1]] = 1
  2380. ret = ret.reshape(ret_shape)
  2381. return ret
  2382. else:
  2383. raise ValueError("Improper number of dimensions to norm.")
  2384. # multi_dot
  2385. def _multidot_dispatcher(arrays, *, out=None):
  2386. yield from arrays
  2387. yield out
  2388. @array_function_dispatch(_multidot_dispatcher)
  2389. def multi_dot(arrays, *, out=None):
  2390. """
  2391. Compute the dot product of two or more arrays in a single function call,
  2392. while automatically selecting the fastest evaluation order.
  2393. `multi_dot` chains `numpy.dot` and uses optimal parenthesization
  2394. of the matrices [1]_ [2]_. Depending on the shapes of the matrices,
  2395. this can speed up the multiplication a lot.
  2396. If the first argument is 1-D it is treated as a row vector.
  2397. If the last argument is 1-D it is treated as a column vector.
  2398. The other arguments must be 2-D.
  2399. Think of `multi_dot` as::
  2400. def multi_dot(arrays): return functools.reduce(np.dot, arrays)
  2401. Parameters
  2402. ----------
  2403. arrays : sequence of array_like
  2404. If the first argument is 1-D it is treated as row vector.
  2405. If the last argument is 1-D it is treated as column vector.
  2406. The other arguments must be 2-D.
  2407. out : ndarray, optional
  2408. Output argument. This must have the exact kind that would be returned
  2409. if it was not used. In particular, it must have the right type, must be
  2410. C-contiguous, and its dtype must be the dtype that would be returned
  2411. for `dot(a, b)`. This is a performance feature. Therefore, if these
  2412. conditions are not met, an exception is raised, instead of attempting
  2413. to be flexible.
  2414. Returns
  2415. -------
  2416. output : ndarray
  2417. Returns the dot product of the supplied arrays.
  2418. See Also
  2419. --------
  2420. numpy.dot : dot multiplication with two arguments.
  2421. References
  2422. ----------
  2423. .. [1] Cormen, "Introduction to Algorithms", Chapter 15.2, p. 370-378
  2424. .. [2] https://en.wikipedia.org/wiki/Matrix_chain_multiplication
  2425. Examples
  2426. --------
  2427. `multi_dot` allows you to write::
  2428. >>> import numpy as np
  2429. >>> from numpy.linalg import multi_dot
  2430. >>> # Prepare some data
  2431. >>> A = np.random.random((10000, 100))
  2432. >>> B = np.random.random((100, 1000))
  2433. >>> C = np.random.random((1000, 5))
  2434. >>> D = np.random.random((5, 333))
  2435. >>> # the actual dot multiplication
  2436. >>> _ = multi_dot([A, B, C, D])
  2437. instead of::
  2438. >>> _ = np.dot(np.dot(np.dot(A, B), C), D)
  2439. >>> # or
  2440. >>> _ = A.dot(B).dot(C).dot(D)
  2441. Notes
  2442. -----
  2443. The cost for a matrix multiplication can be calculated with the
  2444. following function::
  2445. def cost(A, B):
  2446. return A.shape[0] * A.shape[1] * B.shape[1]
  2447. Assume we have three matrices
  2448. :math:`A_{10 \times 100}, B_{100 \times 5}, C_{5 \times 50}`.
  2449. The costs for the two different parenthesizations are as follows::
  2450. cost((AB)C) = 10*100*5 + 10*5*50 = 5000 + 2500 = 7500
  2451. cost(A(BC)) = 10*100*50 + 100*5*50 = 50000 + 25000 = 75000
  2452. """
  2453. n = len(arrays)
  2454. # optimization only makes sense for len(arrays) > 2
  2455. if n < 2:
  2456. raise ValueError("Expecting at least two arrays.")
  2457. elif n == 2:
  2458. return dot(arrays[0], arrays[1], out=out)
  2459. arrays = [asanyarray(a) for a in arrays]
  2460. # save original ndim to reshape the result array into the proper form later
  2461. ndim_first, ndim_last = arrays[0].ndim, arrays[-1].ndim
  2462. # Explicitly convert vectors to 2D arrays to keep the logic of the internal
  2463. # _multi_dot_* functions as simple as possible.
  2464. if arrays[0].ndim == 1:
  2465. arrays[0] = atleast_2d(arrays[0])
  2466. if arrays[-1].ndim == 1:
  2467. arrays[-1] = atleast_2d(arrays[-1]).T
  2468. _assert_2d(*arrays)
  2469. # _multi_dot_three is much faster than _multi_dot_matrix_chain_order
  2470. if n == 3:
  2471. result = _multi_dot_three(arrays[0], arrays[1], arrays[2], out=out)
  2472. else:
  2473. order = _multi_dot_matrix_chain_order(arrays)
  2474. result = _multi_dot(arrays, order, 0, n - 1, out=out)
  2475. # return proper shape
  2476. if ndim_first == 1 and ndim_last == 1:
  2477. return result[0, 0] # scalar
  2478. elif ndim_first == 1 or ndim_last == 1:
  2479. return result.ravel() # 1-D
  2480. else:
  2481. return result
  2482. def _multi_dot_three(A, B, C, out=None):
  2483. """
  2484. Find the best order for three arrays and do the multiplication.
  2485. For three arguments `_multi_dot_three` is approximately 15 times faster
  2486. than `_multi_dot_matrix_chain_order`
  2487. """
  2488. a0, a1b0 = A.shape
  2489. b1c0, c1 = C.shape
  2490. # cost1 = cost((AB)C) = a0*a1b0*b1c0 + a0*b1c0*c1
  2491. cost1 = a0 * b1c0 * (a1b0 + c1)
  2492. # cost2 = cost(A(BC)) = a1b0*b1c0*c1 + a0*a1b0*c1
  2493. cost2 = a1b0 * c1 * (a0 + b1c0)
  2494. if cost1 < cost2:
  2495. return dot(dot(A, B), C, out=out)
  2496. else:
  2497. return dot(A, dot(B, C), out=out)
  2498. def _multi_dot_matrix_chain_order(arrays, return_costs=False):
  2499. """
  2500. Return a np.array that encodes the optimal order of multiplications.
  2501. The optimal order array is then used by `_multi_dot()` to do the
  2502. multiplication.
  2503. Also return the cost matrix if `return_costs` is `True`
  2504. The implementation CLOSELY follows Cormen, "Introduction to Algorithms",
  2505. Chapter 15.2, p. 370-378. Note that Cormen uses 1-based indices.
  2506. cost[i, j] = min([
  2507. cost[prefix] + cost[suffix] + cost_mult(prefix, suffix)
  2508. for k in range(i, j)])
  2509. """
  2510. n = len(arrays)
  2511. # p stores the dimensions of the matrices
  2512. # Example for p: A_{10x100}, B_{100x5}, C_{5x50} --> p = [10, 100, 5, 50]
  2513. p = [a.shape[0] for a in arrays] + [arrays[-1].shape[1]]
  2514. # m is a matrix of costs of the subproblems
  2515. # m[i,j]: min number of scalar multiplications needed to compute A_{i..j}
  2516. m = zeros((n, n), dtype=double)
  2517. # s is the actual ordering
  2518. # s[i, j] is the value of k at which we split the product A_i..A_j
  2519. s = empty((n, n), dtype=intp)
  2520. for l in range(1, n):
  2521. for i in range(n - l):
  2522. j = i + l
  2523. m[i, j] = inf
  2524. for k in range(i, j):
  2525. q = m[i, k] + m[k + 1, j] + p[i] * p[k + 1] * p[j + 1]
  2526. if q < m[i, j]:
  2527. m[i, j] = q
  2528. s[i, j] = k # Note that Cormen uses 1-based index
  2529. return (s, m) if return_costs else s
  2530. def _multi_dot(arrays, order, i, j, out=None):
  2531. """Actually do the multiplication with the given order."""
  2532. if i == j:
  2533. # the initial call with non-None out should never get here
  2534. assert out is None
  2535. return arrays[i]
  2536. else:
  2537. return dot(_multi_dot(arrays, order, i, order[i, j]),
  2538. _multi_dot(arrays, order, order[i, j] + 1, j),
  2539. out=out)
  2540. # diagonal
  2541. def _diagonal_dispatcher(x, /, *, offset=None):
  2542. return (x,)
  2543. @array_function_dispatch(_diagonal_dispatcher)
  2544. def diagonal(x, /, *, offset=0):
  2545. """
  2546. Returns specified diagonals of a matrix (or a stack of matrices) ``x``.
  2547. This function is Array API compatible, contrary to
  2548. :py:func:`numpy.diagonal`, the matrix is assumed
  2549. to be defined by the last two dimensions.
  2550. Parameters
  2551. ----------
  2552. x : (...,M,N) array_like
  2553. Input array having shape (..., M, N) and whose innermost two
  2554. dimensions form MxN matrices.
  2555. offset : int, optional
  2556. Offset specifying the off-diagonal relative to the main diagonal,
  2557. where::
  2558. * offset = 0: the main diagonal.
  2559. * offset > 0: off-diagonal above the main diagonal.
  2560. * offset < 0: off-diagonal below the main diagonal.
  2561. Returns
  2562. -------
  2563. out : (...,min(N,M)) ndarray
  2564. An array containing the diagonals and whose shape is determined by
  2565. removing the last two dimensions and appending a dimension equal to
  2566. the size of the resulting diagonals. The returned array must have
  2567. the same data type as ``x``.
  2568. See Also
  2569. --------
  2570. numpy.diagonal
  2571. Examples
  2572. --------
  2573. >>> a = np.arange(4).reshape(2, 2); a
  2574. array([[0, 1],
  2575. [2, 3]])
  2576. >>> np.linalg.diagonal(a)
  2577. array([0, 3])
  2578. A 3-D example:
  2579. >>> a = np.arange(8).reshape(2, 2, 2); a
  2580. array([[[0, 1],
  2581. [2, 3]],
  2582. [[4, 5],
  2583. [6, 7]]])
  2584. >>> np.linalg.diagonal(a)
  2585. array([[0, 3],
  2586. [4, 7]])
  2587. Diagonals adjacent to the main diagonal can be obtained by using the
  2588. `offset` argument:
  2589. >>> a = np.arange(9).reshape(3, 3)
  2590. >>> a
  2591. array([[0, 1, 2],
  2592. [3, 4, 5],
  2593. [6, 7, 8]])
  2594. >>> np.linalg.diagonal(a, offset=1) # First superdiagonal
  2595. array([1, 5])
  2596. >>> np.linalg.diagonal(a, offset=2) # Second superdiagonal
  2597. array([2])
  2598. >>> np.linalg.diagonal(a, offset=-1) # First subdiagonal
  2599. array([3, 7])
  2600. >>> np.linalg.diagonal(a, offset=-2) # Second subdiagonal
  2601. array([6])
  2602. The anti-diagonal can be obtained by reversing the order of elements
  2603. using either `numpy.flipud` or `numpy.fliplr`.
  2604. >>> a = np.arange(9).reshape(3, 3)
  2605. >>> a
  2606. array([[0, 1, 2],
  2607. [3, 4, 5],
  2608. [6, 7, 8]])
  2609. >>> np.linalg.diagonal(np.fliplr(a)) # Horizontal flip
  2610. array([2, 4, 6])
  2611. >>> np.linalg.diagonal(np.flipud(a)) # Vertical flip
  2612. array([6, 4, 2])
  2613. Note that the order in which the diagonal is retrieved varies depending
  2614. on the flip function.
  2615. """
  2616. return _core_diagonal(x, offset, axis1=-2, axis2=-1)
  2617. # trace
  2618. def _trace_dispatcher(x, /, *, offset=None, dtype=None):
  2619. return (x,)
  2620. @array_function_dispatch(_trace_dispatcher)
  2621. def trace(x, /, *, offset=0, dtype=None):
  2622. """
  2623. Returns the sum along the specified diagonals of a matrix
  2624. (or a stack of matrices) ``x``.
  2625. This function is Array API compatible, contrary to
  2626. :py:func:`numpy.trace`.
  2627. Parameters
  2628. ----------
  2629. x : (...,M,N) array_like
  2630. Input array having shape (..., M, N) and whose innermost two
  2631. dimensions form MxN matrices.
  2632. offset : int, optional
  2633. Offset specifying the off-diagonal relative to the main diagonal,
  2634. where::
  2635. * offset = 0: the main diagonal.
  2636. * offset > 0: off-diagonal above the main diagonal.
  2637. * offset < 0: off-diagonal below the main diagonal.
  2638. dtype : dtype, optional
  2639. Data type of the returned array.
  2640. Returns
  2641. -------
  2642. out : ndarray
  2643. An array containing the traces and whose shape is determined by
  2644. removing the last two dimensions and storing the traces in the last
  2645. array dimension. For example, if x has rank k and shape:
  2646. (I, J, K, ..., L, M, N), then an output array has rank k-2 and shape:
  2647. (I, J, K, ..., L) where::
  2648. out[i, j, k, ..., l] = trace(a[i, j, k, ..., l, :, :])
  2649. The returned array must have a data type as described by the dtype
  2650. parameter above.
  2651. See Also
  2652. --------
  2653. numpy.trace
  2654. Examples
  2655. --------
  2656. >>> np.linalg.trace(np.eye(3))
  2657. 3.0
  2658. >>> a = np.arange(8).reshape((2, 2, 2))
  2659. >>> np.linalg.trace(a)
  2660. array([3, 11])
  2661. Trace is computed with the last two axes as the 2-d sub-arrays.
  2662. This behavior differs from :py:func:`numpy.trace` which uses the first two
  2663. axes by default.
  2664. >>> a = np.arange(24).reshape((3, 2, 2, 2))
  2665. >>> np.linalg.trace(a).shape
  2666. (3, 2)
  2667. Traces adjacent to the main diagonal can be obtained by using the
  2668. `offset` argument:
  2669. >>> a = np.arange(9).reshape((3, 3)); a
  2670. array([[0, 1, 2],
  2671. [3, 4, 5],
  2672. [6, 7, 8]])
  2673. >>> np.linalg.trace(a, offset=1) # First superdiagonal
  2674. 6
  2675. >>> np.linalg.trace(a, offset=2) # Second superdiagonal
  2676. 2
  2677. >>> np.linalg.trace(a, offset=-1) # First subdiagonal
  2678. 10
  2679. >>> np.linalg.trace(a, offset=-2) # Second subdiagonal
  2680. 6
  2681. """
  2682. return _core_trace(x, offset, axis1=-2, axis2=-1, dtype=dtype)
  2683. # cross
  2684. def _cross_dispatcher(x1, x2, /, *, axis=None):
  2685. return (x1, x2,)
  2686. @array_function_dispatch(_cross_dispatcher)
  2687. def cross(x1, x2, /, *, axis=-1):
  2688. """
  2689. Returns the cross product of 3-element vectors.
  2690. If ``x1`` and/or ``x2`` are multi-dimensional arrays, then
  2691. the cross-product of each pair of corresponding 3-element vectors
  2692. is independently computed.
  2693. This function is Array API compatible, contrary to
  2694. :func:`numpy.cross`.
  2695. Parameters
  2696. ----------
  2697. x1 : array_like
  2698. The first input array.
  2699. x2 : array_like
  2700. The second input array. Must be compatible with ``x1`` for all
  2701. non-compute axes. The size of the axis over which to compute
  2702. the cross-product must be the same size as the respective axis
  2703. in ``x1``.
  2704. axis : int, optional
  2705. The axis (dimension) of ``x1`` and ``x2`` containing the vectors for
  2706. which to compute the cross-product. Default: ``-1``.
  2707. Returns
  2708. -------
  2709. out : ndarray
  2710. An array containing the cross products.
  2711. See Also
  2712. --------
  2713. numpy.cross
  2714. Examples
  2715. --------
  2716. Vector cross-product.
  2717. >>> x = np.array([1, 2, 3])
  2718. >>> y = np.array([4, 5, 6])
  2719. >>> np.linalg.cross(x, y)
  2720. array([-3, 6, -3])
  2721. Multiple vector cross-products. Note that the direction of the cross
  2722. product vector is defined by the *right-hand rule*.
  2723. >>> x = np.array([[1,2,3], [4,5,6]])
  2724. >>> y = np.array([[4,5,6], [1,2,3]])
  2725. >>> np.linalg.cross(x, y)
  2726. array([[-3, 6, -3],
  2727. [ 3, -6, 3]])
  2728. >>> x = np.array([[1, 2], [3, 4], [5, 6]])
  2729. >>> y = np.array([[4, 5], [6, 1], [2, 3]])
  2730. >>> np.linalg.cross(x, y, axis=0)
  2731. array([[-24, 6],
  2732. [ 18, 24],
  2733. [-6, -18]])
  2734. """
  2735. x1 = asanyarray(x1)
  2736. x2 = asanyarray(x2)
  2737. if x1.shape[axis] != 3 or x2.shape[axis] != 3:
  2738. raise ValueError(
  2739. "Both input arrays must be (arrays of) 3-dimensional vectors, "
  2740. f"but they are {x1.shape[axis]} and {x2.shape[axis]} "
  2741. "dimensional instead."
  2742. )
  2743. return _core_cross(x1, x2, axis=axis)
  2744. # matmul
  2745. def _matmul_dispatcher(x1, x2, /):
  2746. return (x1, x2)
  2747. @array_function_dispatch(_matmul_dispatcher)
  2748. def matmul(x1, x2, /):
  2749. """
  2750. Computes the matrix product.
  2751. This function is Array API compatible, contrary to
  2752. :func:`numpy.matmul`.
  2753. Parameters
  2754. ----------
  2755. x1 : array_like
  2756. The first input array.
  2757. x2 : array_like
  2758. The second input array.
  2759. Returns
  2760. -------
  2761. out : ndarray
  2762. The matrix product of the inputs.
  2763. This is a scalar only when both ``x1``, ``x2`` are 1-d vectors.
  2764. Raises
  2765. ------
  2766. ValueError
  2767. If the last dimension of ``x1`` is not the same size as
  2768. the second-to-last dimension of ``x2``.
  2769. If a scalar value is passed in.
  2770. See Also
  2771. --------
  2772. numpy.matmul
  2773. Examples
  2774. --------
  2775. For 2-D arrays it is the matrix product:
  2776. >>> a = np.array([[1, 0],
  2777. ... [0, 1]])
  2778. >>> b = np.array([[4, 1],
  2779. ... [2, 2]])
  2780. >>> np.linalg.matmul(a, b)
  2781. array([[4, 1],
  2782. [2, 2]])
  2783. For 2-D mixed with 1-D, the result is the usual.
  2784. >>> a = np.array([[1, 0],
  2785. ... [0, 1]])
  2786. >>> b = np.array([1, 2])
  2787. >>> np.linalg.matmul(a, b)
  2788. array([1, 2])
  2789. >>> np.linalg.matmul(b, a)
  2790. array([1, 2])
  2791. Broadcasting is conventional for stacks of arrays
  2792. >>> a = np.arange(2 * 2 * 4).reshape((2, 2, 4))
  2793. >>> b = np.arange(2 * 2 * 4).reshape((2, 4, 2))
  2794. >>> np.linalg.matmul(a,b).shape
  2795. (2, 2, 2)
  2796. >>> np.linalg.matmul(a, b)[0, 1, 1]
  2797. 98
  2798. >>> sum(a[0, 1, :] * b[0 , :, 1])
  2799. 98
  2800. Vector, vector returns the scalar inner product, but neither argument
  2801. is complex-conjugated:
  2802. >>> np.linalg.matmul([2j, 3j], [2j, 3j])
  2803. (-13+0j)
  2804. Scalar multiplication raises an error.
  2805. >>> np.linalg.matmul([1,2], 3)
  2806. Traceback (most recent call last):
  2807. ...
  2808. ValueError: matmul: Input operand 1 does not have enough dimensions ...
  2809. """
  2810. return _core_matmul(x1, x2)
  2811. # tensordot
  2812. def _tensordot_dispatcher(x1, x2, /, *, axes=None):
  2813. return (x1, x2)
  2814. @array_function_dispatch(_tensordot_dispatcher)
  2815. def tensordot(x1, x2, /, *, axes=2):
  2816. return _core_tensordot(x1, x2, axes=axes)
  2817. tensordot.__doc__ = _core_tensordot.__doc__
  2818. # matrix_transpose
  2819. def _matrix_transpose_dispatcher(x):
  2820. return (x,)
  2821. @array_function_dispatch(_matrix_transpose_dispatcher)
  2822. def matrix_transpose(x, /):
  2823. return _core_matrix_transpose(x)
  2824. matrix_transpose.__doc__ = f"""{_core_matrix_transpose.__doc__}
  2825. Notes
  2826. -----
  2827. This function is an alias of `numpy.matrix_transpose`.
  2828. """
  2829. # matrix_norm
  2830. def _matrix_norm_dispatcher(x, /, *, keepdims=None, ord=None):
  2831. return (x,)
  2832. @array_function_dispatch(_matrix_norm_dispatcher)
  2833. def matrix_norm(x, /, *, keepdims=False, ord="fro"):
  2834. """
  2835. Computes the matrix norm of a matrix (or a stack of matrices) ``x``.
  2836. This function is Array API compatible.
  2837. Parameters
  2838. ----------
  2839. x : array_like
  2840. Input array having shape (..., M, N) and whose two innermost
  2841. dimensions form ``MxN`` matrices.
  2842. keepdims : bool, optional
  2843. If this is set to True, the axes which are normed over are left in
  2844. the result as dimensions with size one. Default: False.
  2845. ord : {1, -1, 2, -2, inf, -inf, 'fro', 'nuc'}, optional
  2846. The order of the norm. For details see the table under ``Notes``
  2847. in `numpy.linalg.norm`.
  2848. See Also
  2849. --------
  2850. numpy.linalg.norm : Generic norm function
  2851. Examples
  2852. --------
  2853. >>> from numpy import linalg as LA
  2854. >>> a = np.arange(9) - 4
  2855. >>> a
  2856. array([-4, -3, -2, ..., 2, 3, 4])
  2857. >>> b = a.reshape((3, 3))
  2858. >>> b
  2859. array([[-4, -3, -2],
  2860. [-1, 0, 1],
  2861. [ 2, 3, 4]])
  2862. >>> LA.matrix_norm(b)
  2863. 7.745966692414834
  2864. >>> LA.matrix_norm(b, ord='fro')
  2865. 7.745966692414834
  2866. >>> LA.matrix_norm(b, ord=np.inf)
  2867. 9.0
  2868. >>> LA.matrix_norm(b, ord=-np.inf)
  2869. 2.0
  2870. >>> LA.matrix_norm(b, ord=1)
  2871. 7.0
  2872. >>> LA.matrix_norm(b, ord=-1)
  2873. 6.0
  2874. >>> LA.matrix_norm(b, ord=2)
  2875. 7.3484692283495345
  2876. >>> LA.matrix_norm(b, ord=-2)
  2877. 1.8570331885190563e-016 # may vary
  2878. """
  2879. x = asanyarray(x)
  2880. return norm(x, axis=(-2, -1), keepdims=keepdims, ord=ord)
  2881. # vector_norm
  2882. def _vector_norm_dispatcher(x, /, *, axis=None, keepdims=None, ord=None):
  2883. return (x,)
  2884. @array_function_dispatch(_vector_norm_dispatcher)
  2885. def vector_norm(x, /, *, axis=None, keepdims=False, ord=2):
  2886. """
  2887. Computes the vector norm of a vector (or batch of vectors) ``x``.
  2888. This function is Array API compatible.
  2889. Parameters
  2890. ----------
  2891. x : array_like
  2892. Input array.
  2893. axis : {None, int, 2-tuple of ints}, optional
  2894. If an integer, ``axis`` specifies the axis (dimension) along which
  2895. to compute vector norms. If an n-tuple, ``axis`` specifies the axes
  2896. (dimensions) along which to compute batched vector norms. If ``None``,
  2897. the vector norm must be computed over all array values (i.e.,
  2898. equivalent to computing the vector norm of a flattened array).
  2899. Default: ``None``.
  2900. keepdims : bool, optional
  2901. If this is set to True, the axes which are normed over are left in
  2902. the result as dimensions with size one. Default: False.
  2903. ord : {int, float, inf, -inf}, optional
  2904. The order of the norm. For details see the table under ``Notes``
  2905. in `numpy.linalg.norm`.
  2906. See Also
  2907. --------
  2908. numpy.linalg.norm : Generic norm function
  2909. Examples
  2910. --------
  2911. >>> from numpy import linalg as LA
  2912. >>> a = np.arange(9) + 1
  2913. >>> a
  2914. array([1, 2, 3, 4, 5, 6, 7, 8, 9])
  2915. >>> b = a.reshape((3, 3))
  2916. >>> b
  2917. array([[1, 2, 3],
  2918. [4, 5, 6],
  2919. [7, 8, 9]])
  2920. >>> LA.vector_norm(b)
  2921. 16.881943016134134
  2922. >>> LA.vector_norm(b, ord=np.inf)
  2923. 9.0
  2924. >>> LA.vector_norm(b, ord=-np.inf)
  2925. 1.0
  2926. >>> LA.vector_norm(b, ord=0)
  2927. 9.0
  2928. >>> LA.vector_norm(b, ord=1)
  2929. 45.0
  2930. >>> LA.vector_norm(b, ord=-1)
  2931. 0.3534857623790153
  2932. >>> LA.vector_norm(b, ord=2)
  2933. 16.881943016134134
  2934. >>> LA.vector_norm(b, ord=-2)
  2935. 0.8058837395885292
  2936. """
  2937. x = asanyarray(x)
  2938. shape = list(x.shape)
  2939. if axis is None:
  2940. # Note: np.linalg.norm() doesn't handle 0-D arrays
  2941. x = x.ravel()
  2942. _axis = 0
  2943. elif isinstance(axis, tuple):
  2944. # Note: The axis argument supports any number of axes, whereas
  2945. # np.linalg.norm() only supports a single axis for vector norm.
  2946. normalized_axis = normalize_axis_tuple(axis, x.ndim)
  2947. rest = tuple(i for i in range(x.ndim) if i not in normalized_axis)
  2948. newshape = axis + rest
  2949. x = _core_transpose(x, newshape).reshape(
  2950. (
  2951. prod([x.shape[i] for i in axis], dtype=int),
  2952. *[x.shape[i] for i in rest]
  2953. )
  2954. )
  2955. _axis = 0
  2956. else:
  2957. _axis = axis
  2958. res = norm(x, axis=_axis, ord=ord)
  2959. if keepdims:
  2960. # We can't reuse np.linalg.norm(keepdims) because of the reshape hacks
  2961. # above to avoid matrix norm logic.
  2962. _axis = normalize_axis_tuple(
  2963. range(len(shape)) if axis is None else axis, len(shape)
  2964. )
  2965. for i in _axis:
  2966. shape[i] = 1
  2967. res = res.reshape(tuple(shape))
  2968. return res
  2969. # vecdot
  2970. def _vecdot_dispatcher(x1, x2, /, *, axis=None):
  2971. return (x1, x2)
  2972. @array_function_dispatch(_vecdot_dispatcher)
  2973. def vecdot(x1, x2, /, *, axis=-1):
  2974. """
  2975. Computes the vector dot product.
  2976. This function is restricted to arguments compatible with the Array API,
  2977. contrary to :func:`numpy.vecdot`.
  2978. Let :math:`\\mathbf{a}` be a vector in ``x1`` and :math:`\\mathbf{b}` be
  2979. a corresponding vector in ``x2``. The dot product is defined as:
  2980. .. math::
  2981. \\mathbf{a} \\cdot \\mathbf{b} = \\sum_{i=0}^{n-1} \\overline{a_i}b_i
  2982. over the dimension specified by ``axis`` and where :math:`\\overline{a_i}`
  2983. denotes the complex conjugate if :math:`a_i` is complex and the identity
  2984. otherwise.
  2985. Parameters
  2986. ----------
  2987. x1 : array_like
  2988. First input array.
  2989. x2 : array_like
  2990. Second input array.
  2991. axis : int, optional
  2992. Axis over which to compute the dot product. Default: ``-1``.
  2993. Returns
  2994. -------
  2995. output : ndarray
  2996. The vector dot product of the input.
  2997. See Also
  2998. --------
  2999. numpy.vecdot
  3000. Examples
  3001. --------
  3002. Get the projected size along a given normal for an array of vectors.
  3003. >>> v = np.array([[0., 5., 0.], [0., 0., 10.], [0., 6., 8.]])
  3004. >>> n = np.array([0., 0.6, 0.8])
  3005. >>> np.linalg.vecdot(v, n)
  3006. array([ 3., 8., 10.])
  3007. """
  3008. return _core_vecdot(x1, x2, axis=axis)