_decomp.py 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Author: Pearu Peterson, March 2002
  4. #
  5. # additions by Travis Oliphant, March 2002
  6. # additions by Eric Jones, June 2002
  7. # additions by Johannes Loehnert, June 2006
  8. # additions by Bart Vandereycken, June 2006
  9. # additions by Andrew D Straw, May 2007
  10. # additions by Tiziano Zito, November 2008
  11. #
  12. # April 2010: Functions for LU, QR, SVD, Schur, and Cholesky decompositions
  13. # were moved to their own files. Still in this file are functions for
  14. # eigenstuff and for the Hessenberg form.
  15. __all__ = ['eig', 'eigvals', 'eigh', 'eigvalsh',
  16. 'eig_banded', 'eigvals_banded',
  17. 'eigh_tridiagonal', 'eigvalsh_tridiagonal', 'hessenberg', 'cdf2rdf']
  18. import warnings
  19. import numpy
  20. from numpy import (array, isfinite, inexact, nonzero, iscomplexobj, cast,
  21. flatnonzero, conj, asarray, argsort, empty,
  22. iscomplex, zeros, einsum, eye, inf)
  23. # Local imports
  24. from scipy._lib._util import _asarray_validated
  25. from ._misc import LinAlgError, _datacopied, norm
  26. from .lapack import get_lapack_funcs, _compute_lwork
  27. _I = cast['F'](1j)
  28. def _make_complex_eigvecs(w, vin, dtype):
  29. """
  30. Produce complex-valued eigenvectors from LAPACK DGGEV real-valued output
  31. """
  32. # - see LAPACK man page DGGEV at ALPHAI
  33. v = numpy.array(vin, dtype=dtype)
  34. m = (w.imag > 0)
  35. m[:-1] |= (w.imag[1:] < 0) # workaround for LAPACK bug, cf. ticket #709
  36. for i in flatnonzero(m):
  37. v.imag[:, i] = vin[:, i+1]
  38. conj(v[:, i], v[:, i+1])
  39. return v
  40. def _make_eigvals(alpha, beta, homogeneous_eigvals):
  41. if homogeneous_eigvals:
  42. if beta is None:
  43. return numpy.vstack((alpha, numpy.ones_like(alpha)))
  44. else:
  45. return numpy.vstack((alpha, beta))
  46. else:
  47. if beta is None:
  48. return alpha
  49. else:
  50. w = numpy.empty_like(alpha)
  51. alpha_zero = (alpha == 0)
  52. beta_zero = (beta == 0)
  53. beta_nonzero = ~beta_zero
  54. w[beta_nonzero] = alpha[beta_nonzero]/beta[beta_nonzero]
  55. # Use numpy.inf for complex values too since
  56. # 1/numpy.inf = 0, i.e., it correctly behaves as projective
  57. # infinity.
  58. w[~alpha_zero & beta_zero] = numpy.inf
  59. if numpy.all(alpha.imag == 0):
  60. w[alpha_zero & beta_zero] = numpy.nan
  61. else:
  62. w[alpha_zero & beta_zero] = complex(numpy.nan, numpy.nan)
  63. return w
  64. def _geneig(a1, b1, left, right, overwrite_a, overwrite_b,
  65. homogeneous_eigvals):
  66. ggev, = get_lapack_funcs(('ggev',), (a1, b1))
  67. cvl, cvr = left, right
  68. res = ggev(a1, b1, lwork=-1)
  69. lwork = res[-2][0].real.astype(numpy.int_)
  70. if ggev.typecode in 'cz':
  71. alpha, beta, vl, vr, work, info = ggev(a1, b1, cvl, cvr, lwork,
  72. overwrite_a, overwrite_b)
  73. w = _make_eigvals(alpha, beta, homogeneous_eigvals)
  74. else:
  75. alphar, alphai, beta, vl, vr, work, info = ggev(a1, b1, cvl, cvr,
  76. lwork, overwrite_a,
  77. overwrite_b)
  78. alpha = alphar + _I * alphai
  79. w = _make_eigvals(alpha, beta, homogeneous_eigvals)
  80. _check_info(info, 'generalized eig algorithm (ggev)')
  81. only_real = numpy.all(w.imag == 0.0)
  82. if not (ggev.typecode in 'cz' or only_real):
  83. t = w.dtype.char
  84. if left:
  85. vl = _make_complex_eigvecs(w, vl, t)
  86. if right:
  87. vr = _make_complex_eigvecs(w, vr, t)
  88. # the eigenvectors returned by the lapack function are NOT normalized
  89. for i in range(vr.shape[0]):
  90. if right:
  91. vr[:, i] /= norm(vr[:, i])
  92. if left:
  93. vl[:, i] /= norm(vl[:, i])
  94. if not (left or right):
  95. return w
  96. if left:
  97. if right:
  98. return w, vl, vr
  99. return w, vl
  100. return w, vr
  101. def eig(a, b=None, left=False, right=True, overwrite_a=False,
  102. overwrite_b=False, check_finite=True, homogeneous_eigvals=False):
  103. """
  104. Solve an ordinary or generalized eigenvalue problem of a square matrix.
  105. Find eigenvalues w and right or left eigenvectors of a general matrix::
  106. a vr[:,i] = w[i] b vr[:,i]
  107. a.H vl[:,i] = w[i].conj() b.H vl[:,i]
  108. where ``.H`` is the Hermitian conjugation.
  109. Parameters
  110. ----------
  111. a : (M, M) array_like
  112. A complex or real matrix whose eigenvalues and eigenvectors
  113. will be computed.
  114. b : (M, M) array_like, optional
  115. Right-hand side matrix in a generalized eigenvalue problem.
  116. Default is None, identity matrix is assumed.
  117. left : bool, optional
  118. Whether to calculate and return left eigenvectors. Default is False.
  119. right : bool, optional
  120. Whether to calculate and return right eigenvectors. Default is True.
  121. overwrite_a : bool, optional
  122. Whether to overwrite `a`; may improve performance. Default is False.
  123. overwrite_b : bool, optional
  124. Whether to overwrite `b`; may improve performance. Default is False.
  125. check_finite : bool, optional
  126. Whether to check that the input matrices contain only finite numbers.
  127. Disabling may give a performance gain, but may result in problems
  128. (crashes, non-termination) if the inputs do contain infinities or NaNs.
  129. homogeneous_eigvals : bool, optional
  130. If True, return the eigenvalues in homogeneous coordinates.
  131. In this case ``w`` is a (2, M) array so that::
  132. w[1,i] a vr[:,i] = w[0,i] b vr[:,i]
  133. Default is False.
  134. Returns
  135. -------
  136. w : (M,) or (2, M) double or complex ndarray
  137. The eigenvalues, each repeated according to its
  138. multiplicity. The shape is (M,) unless
  139. ``homogeneous_eigvals=True``.
  140. vl : (M, M) double or complex ndarray
  141. The normalized left eigenvector corresponding to the eigenvalue
  142. ``w[i]`` is the column vl[:,i]. Only returned if ``left=True``.
  143. vr : (M, M) double or complex ndarray
  144. The normalized right eigenvector corresponding to the eigenvalue
  145. ``w[i]`` is the column ``vr[:,i]``. Only returned if ``right=True``.
  146. Raises
  147. ------
  148. LinAlgError
  149. If eigenvalue computation does not converge.
  150. See Also
  151. --------
  152. eigvals : eigenvalues of general arrays
  153. eigh : Eigenvalues and right eigenvectors for symmetric/Hermitian arrays.
  154. eig_banded : eigenvalues and right eigenvectors for symmetric/Hermitian
  155. band matrices
  156. eigh_tridiagonal : eigenvalues and right eiegenvectors for
  157. symmetric/Hermitian tridiagonal matrices
  158. Examples
  159. --------
  160. >>> import numpy as np
  161. >>> from scipy import linalg
  162. >>> a = np.array([[0., -1.], [1., 0.]])
  163. >>> linalg.eigvals(a)
  164. array([0.+1.j, 0.-1.j])
  165. >>> b = np.array([[0., 1.], [1., 1.]])
  166. >>> linalg.eigvals(a, b)
  167. array([ 1.+0.j, -1.+0.j])
  168. >>> a = np.array([[3., 0., 0.], [0., 8., 0.], [0., 0., 7.]])
  169. >>> linalg.eigvals(a, homogeneous_eigvals=True)
  170. array([[3.+0.j, 8.+0.j, 7.+0.j],
  171. [1.+0.j, 1.+0.j, 1.+0.j]])
  172. >>> a = np.array([[0., -1.], [1., 0.]])
  173. >>> linalg.eigvals(a) == linalg.eig(a)[0]
  174. array([ True, True])
  175. >>> linalg.eig(a, left=True, right=False)[1] # normalized left eigenvector
  176. array([[-0.70710678+0.j , -0.70710678-0.j ],
  177. [-0. +0.70710678j, -0. -0.70710678j]])
  178. >>> linalg.eig(a, left=False, right=True)[1] # normalized right eigenvector
  179. array([[0.70710678+0.j , 0.70710678-0.j ],
  180. [0. -0.70710678j, 0. +0.70710678j]])
  181. """
  182. a1 = _asarray_validated(a, check_finite=check_finite)
  183. if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
  184. raise ValueError('expected square matrix')
  185. overwrite_a = overwrite_a or (_datacopied(a1, a))
  186. if b is not None:
  187. b1 = _asarray_validated(b, check_finite=check_finite)
  188. overwrite_b = overwrite_b or _datacopied(b1, b)
  189. if len(b1.shape) != 2 or b1.shape[0] != b1.shape[1]:
  190. raise ValueError('expected square matrix')
  191. if b1.shape != a1.shape:
  192. raise ValueError('a and b must have the same shape')
  193. return _geneig(a1, b1, left, right, overwrite_a, overwrite_b,
  194. homogeneous_eigvals)
  195. geev, geev_lwork = get_lapack_funcs(('geev', 'geev_lwork'), (a1,))
  196. compute_vl, compute_vr = left, right
  197. lwork = _compute_lwork(geev_lwork, a1.shape[0],
  198. compute_vl=compute_vl,
  199. compute_vr=compute_vr)
  200. if geev.typecode in 'cz':
  201. w, vl, vr, info = geev(a1, lwork=lwork,
  202. compute_vl=compute_vl,
  203. compute_vr=compute_vr,
  204. overwrite_a=overwrite_a)
  205. w = _make_eigvals(w, None, homogeneous_eigvals)
  206. else:
  207. wr, wi, vl, vr, info = geev(a1, lwork=lwork,
  208. compute_vl=compute_vl,
  209. compute_vr=compute_vr,
  210. overwrite_a=overwrite_a)
  211. t = {'f': 'F', 'd': 'D'}[wr.dtype.char]
  212. w = wr + _I * wi
  213. w = _make_eigvals(w, None, homogeneous_eigvals)
  214. _check_info(info, 'eig algorithm (geev)',
  215. positive='did not converge (only eigenvalues '
  216. 'with order >= %d have converged)')
  217. only_real = numpy.all(w.imag == 0.0)
  218. if not (geev.typecode in 'cz' or only_real):
  219. t = w.dtype.char
  220. if left:
  221. vl = _make_complex_eigvecs(w, vl, t)
  222. if right:
  223. vr = _make_complex_eigvecs(w, vr, t)
  224. if not (left or right):
  225. return w
  226. if left:
  227. if right:
  228. return w, vl, vr
  229. return w, vl
  230. return w, vr
  231. def eigh(a, b=None, lower=True, eigvals_only=False, overwrite_a=False,
  232. overwrite_b=False, turbo=False, eigvals=None, type=1,
  233. check_finite=True, subset_by_index=None, subset_by_value=None,
  234. driver=None):
  235. """
  236. Solve a standard or generalized eigenvalue problem for a complex
  237. Hermitian or real symmetric matrix.
  238. Find eigenvalues array ``w`` and optionally eigenvectors array ``v`` of
  239. array ``a``, where ``b`` is positive definite such that for every
  240. eigenvalue λ (i-th entry of w) and its eigenvector ``vi`` (i-th column of
  241. ``v``) satisfies::
  242. a @ vi = λ * b @ vi
  243. vi.conj().T @ a @ vi = λ
  244. vi.conj().T @ b @ vi = 1
  245. In the standard problem, ``b`` is assumed to be the identity matrix.
  246. Parameters
  247. ----------
  248. a : (M, M) array_like
  249. A complex Hermitian or real symmetric matrix whose eigenvalues and
  250. eigenvectors will be computed.
  251. b : (M, M) array_like, optional
  252. A complex Hermitian or real symmetric definite positive matrix in.
  253. If omitted, identity matrix is assumed.
  254. lower : bool, optional
  255. Whether the pertinent array data is taken from the lower or upper
  256. triangle of ``a`` and, if applicable, ``b``. (Default: lower)
  257. eigvals_only : bool, optional
  258. Whether to calculate only eigenvalues and no eigenvectors.
  259. (Default: both are calculated)
  260. subset_by_index : iterable, optional
  261. If provided, this two-element iterable defines the start and the end
  262. indices of the desired eigenvalues (ascending order and 0-indexed).
  263. To return only the second smallest to fifth smallest eigenvalues,
  264. ``[1, 4]`` is used. ``[n-3, n-1]`` returns the largest three. Only
  265. available with "evr", "evx", and "gvx" drivers. The entries are
  266. directly converted to integers via ``int()``.
  267. subset_by_value : iterable, optional
  268. If provided, this two-element iterable defines the half-open interval
  269. ``(a, b]`` that, if any, only the eigenvalues between these values
  270. are returned. Only available with "evr", "evx", and "gvx" drivers. Use
  271. ``np.inf`` for the unconstrained ends.
  272. driver : str, optional
  273. Defines which LAPACK driver should be used. Valid options are "ev",
  274. "evd", "evr", "evx" for standard problems and "gv", "gvd", "gvx" for
  275. generalized (where b is not None) problems. See the Notes section.
  276. The default for standard problems is "evr". For generalized problems,
  277. "gvd" is used for full set, and "gvx" for subset requested cases.
  278. type : int, optional
  279. For the generalized problems, this keyword specifies the problem type
  280. to be solved for ``w`` and ``v`` (only takes 1, 2, 3 as possible
  281. inputs)::
  282. 1 => a @ v = w @ b @ v
  283. 2 => a @ b @ v = w @ v
  284. 3 => b @ a @ v = w @ v
  285. This keyword is ignored for standard problems.
  286. overwrite_a : bool, optional
  287. Whether to overwrite data in ``a`` (may improve performance). Default
  288. is False.
  289. overwrite_b : bool, optional
  290. Whether to overwrite data in ``b`` (may improve performance). Default
  291. is False.
  292. check_finite : bool, optional
  293. Whether to check that the input matrices contain only finite numbers.
  294. Disabling may give a performance gain, but may result in problems
  295. (crashes, non-termination) if the inputs do contain infinities or NaNs.
  296. turbo : bool, optional, deprecated
  297. .. deprecated:: 1.5.0
  298. `eigh` keyword argument `turbo` is deprecated in favour of
  299. ``driver=gvd`` keyword instead and will be removed in SciPy
  300. 1.12.0.
  301. eigvals : tuple (lo, hi), optional, deprecated
  302. .. deprecated:: 1.5.0
  303. `eigh` keyword argument `eigvals` is deprecated in favour of
  304. `subset_by_index` keyword instead and will be removed in SciPy
  305. 1.12.0.
  306. Returns
  307. -------
  308. w : (N,) ndarray
  309. The N (1<=N<=M) selected eigenvalues, in ascending order, each
  310. repeated according to its multiplicity.
  311. v : (M, N) ndarray
  312. (if ``eigvals_only == False``)
  313. Raises
  314. ------
  315. LinAlgError
  316. If eigenvalue computation does not converge, an error occurred, or
  317. b matrix is not definite positive. Note that if input matrices are
  318. not symmetric or Hermitian, no error will be reported but results will
  319. be wrong.
  320. See Also
  321. --------
  322. eigvalsh : eigenvalues of symmetric or Hermitian arrays
  323. eig : eigenvalues and right eigenvectors for non-symmetric arrays
  324. eigh_tridiagonal : eigenvalues and right eiegenvectors for
  325. symmetric/Hermitian tridiagonal matrices
  326. Notes
  327. -----
  328. This function does not check the input array for being Hermitian/symmetric
  329. in order to allow for representing arrays with only their upper/lower
  330. triangular parts. Also, note that even though not taken into account,
  331. finiteness check applies to the whole array and unaffected by "lower"
  332. keyword.
  333. This function uses LAPACK drivers for computations in all possible keyword
  334. combinations, prefixed with ``sy`` if arrays are real and ``he`` if
  335. complex, e.g., a float array with "evr" driver is solved via
  336. "syevr", complex arrays with "gvx" driver problem is solved via "hegvx"
  337. etc.
  338. As a brief summary, the slowest and the most robust driver is the
  339. classical ``<sy/he>ev`` which uses symmetric QR. ``<sy/he>evr`` is seen as
  340. the optimal choice for the most general cases. However, there are certain
  341. occasions that ``<sy/he>evd`` computes faster at the expense of more
  342. memory usage. ``<sy/he>evx``, while still being faster than ``<sy/he>ev``,
  343. often performs worse than the rest except when very few eigenvalues are
  344. requested for large arrays though there is still no performance guarantee.
  345. For the generalized problem, normalization with respect to the given
  346. type argument::
  347. type 1 and 3 : v.conj().T @ a @ v = w
  348. type 2 : inv(v).conj().T @ a @ inv(v) = w
  349. type 1 or 2 : v.conj().T @ b @ v = I
  350. type 3 : v.conj().T @ inv(b) @ v = I
  351. Examples
  352. --------
  353. >>> import numpy as np
  354. >>> from scipy.linalg import eigh
  355. >>> A = np.array([[6, 3, 1, 5], [3, 0, 5, 1], [1, 5, 6, 2], [5, 1, 2, 2]])
  356. >>> w, v = eigh(A)
  357. >>> np.allclose(A @ v - v @ np.diag(w), np.zeros((4, 4)))
  358. True
  359. Request only the eigenvalues
  360. >>> w = eigh(A, eigvals_only=True)
  361. Request eigenvalues that are less than 10.
  362. >>> A = np.array([[34, -4, -10, -7, 2],
  363. ... [-4, 7, 2, 12, 0],
  364. ... [-10, 2, 44, 2, -19],
  365. ... [-7, 12, 2, 79, -34],
  366. ... [2, 0, -19, -34, 29]])
  367. >>> eigh(A, eigvals_only=True, subset_by_value=[-np.inf, 10])
  368. array([6.69199443e-07, 9.11938152e+00])
  369. Request the second smallest eigenvalue and its eigenvector
  370. >>> w, v = eigh(A, subset_by_index=[1, 1])
  371. >>> w
  372. array([9.11938152])
  373. >>> v.shape # only a single column is returned
  374. (5, 1)
  375. """
  376. if turbo:
  377. warnings.warn("Keyword argument 'turbo' is deprecated in favour of '"
  378. "driver=gvd' keyword instead and will be removed in "
  379. "SciPy 1.12.0.",
  380. DeprecationWarning, stacklevel=2)
  381. if eigvals:
  382. warnings.warn("Keyword argument 'eigvals' is deprecated in favour of "
  383. "'subset_by_index' keyword instead and will be removed "
  384. "in SciPy 1.12.0.",
  385. DeprecationWarning, stacklevel=2)
  386. # set lower
  387. uplo = 'L' if lower else 'U'
  388. # Set job for Fortran routines
  389. _job = 'N' if eigvals_only else 'V'
  390. drv_str = [None, "ev", "evd", "evr", "evx", "gv", "gvd", "gvx"]
  391. if driver not in drv_str:
  392. raise ValueError('"{}" is unknown. Possible values are "None", "{}".'
  393. ''.format(driver, '", "'.join(drv_str[1:])))
  394. a1 = _asarray_validated(a, check_finite=check_finite)
  395. if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
  396. raise ValueError('expected square "a" matrix')
  397. overwrite_a = overwrite_a or (_datacopied(a1, a))
  398. cplx = True if iscomplexobj(a1) else False
  399. n = a1.shape[0]
  400. drv_args = {'overwrite_a': overwrite_a}
  401. if b is not None:
  402. b1 = _asarray_validated(b, check_finite=check_finite)
  403. overwrite_b = overwrite_b or _datacopied(b1, b)
  404. if len(b1.shape) != 2 or b1.shape[0] != b1.shape[1]:
  405. raise ValueError('expected square "b" matrix')
  406. if b1.shape != a1.shape:
  407. raise ValueError("wrong b dimensions {}, should "
  408. "be {}".format(b1.shape, a1.shape))
  409. if type not in [1, 2, 3]:
  410. raise ValueError('"type" keyword only accepts 1, 2, and 3.')
  411. cplx = True if iscomplexobj(b1) else (cplx or False)
  412. drv_args.update({'overwrite_b': overwrite_b, 'itype': type})
  413. # backwards-compatibility handling
  414. subset_by_index = subset_by_index if (eigvals is None) else eigvals
  415. subset = (subset_by_index is not None) or (subset_by_value is not None)
  416. # Both subsets can't be given
  417. if subset_by_index and subset_by_value:
  418. raise ValueError('Either index or value subset can be requested.')
  419. # Take turbo into account if all conditions are met otherwise ignore
  420. if turbo and b is not None:
  421. driver = 'gvx' if subset else 'gvd'
  422. # Check indices if given
  423. if subset_by_index:
  424. lo, hi = [int(x) for x in subset_by_index]
  425. if not (0 <= lo <= hi < n):
  426. raise ValueError('Requested eigenvalue indices are not valid. '
  427. 'Valid range is [0, {}] and start <= end, but '
  428. 'start={}, end={} is given'.format(n-1, lo, hi))
  429. # fortran is 1-indexed
  430. drv_args.update({'range': 'I', 'il': lo + 1, 'iu': hi + 1})
  431. if subset_by_value:
  432. lo, hi = subset_by_value
  433. if not (-inf <= lo < hi <= inf):
  434. raise ValueError('Requested eigenvalue bounds are not valid. '
  435. 'Valid range is (-inf, inf) and low < high, but '
  436. 'low={}, high={} is given'.format(lo, hi))
  437. drv_args.update({'range': 'V', 'vl': lo, 'vu': hi})
  438. # fix prefix for lapack routines
  439. pfx = 'he' if cplx else 'sy'
  440. # decide on the driver if not given
  441. # first early exit on incompatible choice
  442. if driver:
  443. if b is None and (driver in ["gv", "gvd", "gvx"]):
  444. raise ValueError('{} requires input b array to be supplied '
  445. 'for generalized eigenvalue problems.'
  446. ''.format(driver))
  447. if (b is not None) and (driver in ['ev', 'evd', 'evr', 'evx']):
  448. raise ValueError('"{}" does not accept input b array '
  449. 'for standard eigenvalue problems.'
  450. ''.format(driver))
  451. if subset and (driver in ["ev", "evd", "gv", "gvd"]):
  452. raise ValueError('"{}" cannot compute subsets of eigenvalues'
  453. ''.format(driver))
  454. # Default driver is evr and gvd
  455. else:
  456. driver = "evr" if b is None else ("gvx" if subset else "gvd")
  457. lwork_spec = {
  458. 'syevd': ['lwork', 'liwork'],
  459. 'syevr': ['lwork', 'liwork'],
  460. 'heevd': ['lwork', 'liwork', 'lrwork'],
  461. 'heevr': ['lwork', 'lrwork', 'liwork'],
  462. }
  463. if b is None: # Standard problem
  464. drv, drvlw = get_lapack_funcs((pfx + driver, pfx+driver+'_lwork'),
  465. [a1])
  466. clw_args = {'n': n, 'lower': lower}
  467. if driver == 'evd':
  468. clw_args.update({'compute_v': 0 if _job == "N" else 1})
  469. lw = _compute_lwork(drvlw, **clw_args)
  470. # Multiple lwork vars
  471. if isinstance(lw, tuple):
  472. lwork_args = dict(zip(lwork_spec[pfx+driver], lw))
  473. else:
  474. lwork_args = {'lwork': lw}
  475. drv_args.update({'lower': lower, 'compute_v': 0 if _job == "N" else 1})
  476. w, v, *other_args, info = drv(a=a1, **drv_args, **lwork_args)
  477. else: # Generalized problem
  478. # 'gvd' doesn't have lwork query
  479. if driver == "gvd":
  480. drv = get_lapack_funcs(pfx + "gvd", [a1, b1])
  481. lwork_args = {}
  482. else:
  483. drv, drvlw = get_lapack_funcs((pfx + driver, pfx+driver+'_lwork'),
  484. [a1, b1])
  485. # generalized drivers use uplo instead of lower
  486. lw = _compute_lwork(drvlw, n, uplo=uplo)
  487. lwork_args = {'lwork': lw}
  488. drv_args.update({'uplo': uplo, 'jobz': _job})
  489. w, v, *other_args, info = drv(a=a1, b=b1, **drv_args, **lwork_args)
  490. # m is always the first extra argument
  491. w = w[:other_args[0]] if subset else w
  492. v = v[:, :other_args[0]] if (subset and not eigvals_only) else v
  493. # Check if we had a successful exit
  494. if info == 0:
  495. if eigvals_only:
  496. return w
  497. else:
  498. return w, v
  499. else:
  500. if info < -1:
  501. raise LinAlgError('Illegal value in argument {} of internal {}'
  502. ''.format(-info, drv.typecode + pfx + driver))
  503. elif info > n:
  504. raise LinAlgError('The leading minor of order {} of B is not '
  505. 'positive definite. The factorization of B '
  506. 'could not be completed and no eigenvalues '
  507. 'or eigenvectors were computed.'.format(info-n))
  508. else:
  509. drv_err = {'ev': 'The algorithm failed to converge; {} '
  510. 'off-diagonal elements of an intermediate '
  511. 'tridiagonal form did not converge to zero.',
  512. 'evx': '{} eigenvectors failed to converge.',
  513. 'evd': 'The algorithm failed to compute an eigenvalue '
  514. 'while working on the submatrix lying in rows '
  515. 'and columns {0}/{1} through mod({0},{1}).',
  516. 'evr': 'Internal Error.'
  517. }
  518. if driver in ['ev', 'gv']:
  519. msg = drv_err['ev'].format(info)
  520. elif driver in ['evx', 'gvx']:
  521. msg = drv_err['evx'].format(info)
  522. elif driver in ['evd', 'gvd']:
  523. if eigvals_only:
  524. msg = drv_err['ev'].format(info)
  525. else:
  526. msg = drv_err['evd'].format(info, n+1)
  527. else:
  528. msg = drv_err['evr']
  529. raise LinAlgError(msg)
  530. _conv_dict = {0: 0, 1: 1, 2: 2,
  531. 'all': 0, 'value': 1, 'index': 2,
  532. 'a': 0, 'v': 1, 'i': 2}
  533. def _check_select(select, select_range, max_ev, max_len):
  534. """Check that select is valid, convert to Fortran style."""
  535. if isinstance(select, str):
  536. select = select.lower()
  537. try:
  538. select = _conv_dict[select]
  539. except KeyError as e:
  540. raise ValueError('invalid argument for select') from e
  541. vl, vu = 0., 1.
  542. il = iu = 1
  543. if select != 0: # (non-all)
  544. sr = asarray(select_range)
  545. if sr.ndim != 1 or sr.size != 2 or sr[1] < sr[0]:
  546. raise ValueError('select_range must be a 2-element array-like '
  547. 'in nondecreasing order')
  548. if select == 1: # (value)
  549. vl, vu = sr
  550. if max_ev == 0:
  551. max_ev = max_len
  552. else: # 2 (index)
  553. if sr.dtype.char.lower() not in 'hilqp':
  554. raise ValueError('when using select="i", select_range must '
  555. 'contain integers, got dtype %s (%s)'
  556. % (sr.dtype, sr.dtype.char))
  557. # translate Python (0 ... N-1) into Fortran (1 ... N) with + 1
  558. il, iu = sr + 1
  559. if min(il, iu) < 1 or max(il, iu) > max_len:
  560. raise ValueError('select_range out of bounds')
  561. max_ev = iu - il + 1
  562. return select, vl, vu, il, iu, max_ev
  563. def eig_banded(a_band, lower=False, eigvals_only=False, overwrite_a_band=False,
  564. select='a', select_range=None, max_ev=0, check_finite=True):
  565. """
  566. Solve real symmetric or complex Hermitian band matrix eigenvalue problem.
  567. Find eigenvalues w and optionally right eigenvectors v of a::
  568. a v[:,i] = w[i] v[:,i]
  569. v.H v = identity
  570. The matrix a is stored in a_band either in lower diagonal or upper
  571. diagonal ordered form:
  572. a_band[u + i - j, j] == a[i,j] (if upper form; i <= j)
  573. a_band[ i - j, j] == a[i,j] (if lower form; i >= j)
  574. where u is the number of bands above the diagonal.
  575. Example of a_band (shape of a is (6,6), u=2)::
  576. upper form:
  577. * * a02 a13 a24 a35
  578. * a01 a12 a23 a34 a45
  579. a00 a11 a22 a33 a44 a55
  580. lower form:
  581. a00 a11 a22 a33 a44 a55
  582. a10 a21 a32 a43 a54 *
  583. a20 a31 a42 a53 * *
  584. Cells marked with * are not used.
  585. Parameters
  586. ----------
  587. a_band : (u+1, M) array_like
  588. The bands of the M by M matrix a.
  589. lower : bool, optional
  590. Is the matrix in the lower form. (Default is upper form)
  591. eigvals_only : bool, optional
  592. Compute only the eigenvalues and no eigenvectors.
  593. (Default: calculate also eigenvectors)
  594. overwrite_a_band : bool, optional
  595. Discard data in a_band (may enhance performance)
  596. select : {'a', 'v', 'i'}, optional
  597. Which eigenvalues to calculate
  598. ====== ========================================
  599. select calculated
  600. ====== ========================================
  601. 'a' All eigenvalues
  602. 'v' Eigenvalues in the interval (min, max]
  603. 'i' Eigenvalues with indices min <= i <= max
  604. ====== ========================================
  605. select_range : (min, max), optional
  606. Range of selected eigenvalues
  607. max_ev : int, optional
  608. For select=='v', maximum number of eigenvalues expected.
  609. For other values of select, has no meaning.
  610. In doubt, leave this parameter untouched.
  611. check_finite : bool, optional
  612. Whether to check that the input matrix contains only finite numbers.
  613. Disabling may give a performance gain, but may result in problems
  614. (crashes, non-termination) if the inputs do contain infinities or NaNs.
  615. Returns
  616. -------
  617. w : (M,) ndarray
  618. The eigenvalues, in ascending order, each repeated according to its
  619. multiplicity.
  620. v : (M, M) float or complex ndarray
  621. The normalized eigenvector corresponding to the eigenvalue w[i] is
  622. the column v[:,i].
  623. Raises
  624. ------
  625. LinAlgError
  626. If eigenvalue computation does not converge.
  627. See Also
  628. --------
  629. eigvals_banded : eigenvalues for symmetric/Hermitian band matrices
  630. eig : eigenvalues and right eigenvectors of general arrays.
  631. eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
  632. eigh_tridiagonal : eigenvalues and right eigenvectors for
  633. symmetric/Hermitian tridiagonal matrices
  634. Examples
  635. --------
  636. >>> import numpy as np
  637. >>> from scipy.linalg import eig_banded
  638. >>> A = np.array([[1, 5, 2, 0], [5, 2, 5, 2], [2, 5, 3, 5], [0, 2, 5, 4]])
  639. >>> Ab = np.array([[1, 2, 3, 4], [5, 5, 5, 0], [2, 2, 0, 0]])
  640. >>> w, v = eig_banded(Ab, lower=True)
  641. >>> np.allclose(A @ v - v @ np.diag(w), np.zeros((4, 4)))
  642. True
  643. >>> w = eig_banded(Ab, lower=True, eigvals_only=True)
  644. >>> w
  645. array([-4.26200532, -2.22987175, 3.95222349, 12.53965359])
  646. Request only the eigenvalues between ``[-3, 4]``
  647. >>> w, v = eig_banded(Ab, lower=True, select='v', select_range=[-3, 4])
  648. >>> w
  649. array([-2.22987175, 3.95222349])
  650. """
  651. if eigvals_only or overwrite_a_band:
  652. a1 = _asarray_validated(a_band, check_finite=check_finite)
  653. overwrite_a_band = overwrite_a_band or (_datacopied(a1, a_band))
  654. else:
  655. a1 = array(a_band)
  656. if issubclass(a1.dtype.type, inexact) and not isfinite(a1).all():
  657. raise ValueError("array must not contain infs or NaNs")
  658. overwrite_a_band = 1
  659. if len(a1.shape) != 2:
  660. raise ValueError('expected a 2-D array')
  661. select, vl, vu, il, iu, max_ev = _check_select(
  662. select, select_range, max_ev, a1.shape[1])
  663. del select_range
  664. if select == 0:
  665. if a1.dtype.char in 'GFD':
  666. # FIXME: implement this somewhen, for now go with builtin values
  667. # FIXME: calc optimal lwork by calling ?hbevd(lwork=-1)
  668. # or by using calc_lwork.f ???
  669. # lwork = calc_lwork.hbevd(bevd.typecode, a1.shape[0], lower)
  670. internal_name = 'hbevd'
  671. else: # a1.dtype.char in 'fd':
  672. # FIXME: implement this somewhen, for now go with builtin values
  673. # see above
  674. # lwork = calc_lwork.sbevd(bevd.typecode, a1.shape[0], lower)
  675. internal_name = 'sbevd'
  676. bevd, = get_lapack_funcs((internal_name,), (a1,))
  677. w, v, info = bevd(a1, compute_v=not eigvals_only,
  678. lower=lower, overwrite_ab=overwrite_a_band)
  679. else: # select in [1, 2]
  680. if eigvals_only:
  681. max_ev = 1
  682. # calculate optimal abstol for dsbevx (see manpage)
  683. if a1.dtype.char in 'fF': # single precision
  684. lamch, = get_lapack_funcs(('lamch',), (array(0, dtype='f'),))
  685. else:
  686. lamch, = get_lapack_funcs(('lamch',), (array(0, dtype='d'),))
  687. abstol = 2 * lamch('s')
  688. if a1.dtype.char in 'GFD':
  689. internal_name = 'hbevx'
  690. else: # a1.dtype.char in 'gfd'
  691. internal_name = 'sbevx'
  692. bevx, = get_lapack_funcs((internal_name,), (a1,))
  693. w, v, m, ifail, info = bevx(
  694. a1, vl, vu, il, iu, compute_v=not eigvals_only, mmax=max_ev,
  695. range=select, lower=lower, overwrite_ab=overwrite_a_band,
  696. abstol=abstol)
  697. # crop off w and v
  698. w = w[:m]
  699. if not eigvals_only:
  700. v = v[:, :m]
  701. _check_info(info, internal_name)
  702. if eigvals_only:
  703. return w
  704. return w, v
  705. def eigvals(a, b=None, overwrite_a=False, check_finite=True,
  706. homogeneous_eigvals=False):
  707. """
  708. Compute eigenvalues from an ordinary or generalized eigenvalue problem.
  709. Find eigenvalues of a general matrix::
  710. a vr[:,i] = w[i] b vr[:,i]
  711. Parameters
  712. ----------
  713. a : (M, M) array_like
  714. A complex or real matrix whose eigenvalues and eigenvectors
  715. will be computed.
  716. b : (M, M) array_like, optional
  717. Right-hand side matrix in a generalized eigenvalue problem.
  718. If omitted, identity matrix is assumed.
  719. overwrite_a : bool, optional
  720. Whether to overwrite data in a (may improve performance)
  721. check_finite : bool, optional
  722. Whether to check that the input matrices contain only finite numbers.
  723. Disabling may give a performance gain, but may result in problems
  724. (crashes, non-termination) if the inputs do contain infinities
  725. or NaNs.
  726. homogeneous_eigvals : bool, optional
  727. If True, return the eigenvalues in homogeneous coordinates.
  728. In this case ``w`` is a (2, M) array so that::
  729. w[1,i] a vr[:,i] = w[0,i] b vr[:,i]
  730. Default is False.
  731. Returns
  732. -------
  733. w : (M,) or (2, M) double or complex ndarray
  734. The eigenvalues, each repeated according to its multiplicity
  735. but not in any specific order. The shape is (M,) unless
  736. ``homogeneous_eigvals=True``.
  737. Raises
  738. ------
  739. LinAlgError
  740. If eigenvalue computation does not converge
  741. See Also
  742. --------
  743. eig : eigenvalues and right eigenvectors of general arrays.
  744. eigvalsh : eigenvalues of symmetric or Hermitian arrays
  745. eigvals_banded : eigenvalues for symmetric/Hermitian band matrices
  746. eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
  747. matrices
  748. Examples
  749. --------
  750. >>> import numpy as np
  751. >>> from scipy import linalg
  752. >>> a = np.array([[0., -1.], [1., 0.]])
  753. >>> linalg.eigvals(a)
  754. array([0.+1.j, 0.-1.j])
  755. >>> b = np.array([[0., 1.], [1., 1.]])
  756. >>> linalg.eigvals(a, b)
  757. array([ 1.+0.j, -1.+0.j])
  758. >>> a = np.array([[3., 0., 0.], [0., 8., 0.], [0., 0., 7.]])
  759. >>> linalg.eigvals(a, homogeneous_eigvals=True)
  760. array([[3.+0.j, 8.+0.j, 7.+0.j],
  761. [1.+0.j, 1.+0.j, 1.+0.j]])
  762. """
  763. return eig(a, b=b, left=0, right=0, overwrite_a=overwrite_a,
  764. check_finite=check_finite,
  765. homogeneous_eigvals=homogeneous_eigvals)
  766. def eigvalsh(a, b=None, lower=True, overwrite_a=False,
  767. overwrite_b=False, turbo=False, eigvals=None, type=1,
  768. check_finite=True, subset_by_index=None, subset_by_value=None,
  769. driver=None):
  770. """
  771. Solves a standard or generalized eigenvalue problem for a complex
  772. Hermitian or real symmetric matrix.
  773. Find eigenvalues array ``w`` of array ``a``, where ``b`` is positive
  774. definite such that for every eigenvalue λ (i-th entry of w) and its
  775. eigenvector vi (i-th column of v) satisfies::
  776. a @ vi = λ * b @ vi
  777. vi.conj().T @ a @ vi = λ
  778. vi.conj().T @ b @ vi = 1
  779. In the standard problem, b is assumed to be the identity matrix.
  780. Parameters
  781. ----------
  782. a : (M, M) array_like
  783. A complex Hermitian or real symmetric matrix whose eigenvalues will
  784. be computed.
  785. b : (M, M) array_like, optional
  786. A complex Hermitian or real symmetric definite positive matrix in.
  787. If omitted, identity matrix is assumed.
  788. lower : bool, optional
  789. Whether the pertinent array data is taken from the lower or upper
  790. triangle of ``a`` and, if applicable, ``b``. (Default: lower)
  791. overwrite_a : bool, optional
  792. Whether to overwrite data in ``a`` (may improve performance). Default
  793. is False.
  794. overwrite_b : bool, optional
  795. Whether to overwrite data in ``b`` (may improve performance). Default
  796. is False.
  797. type : int, optional
  798. For the generalized problems, this keyword specifies the problem type
  799. to be solved for ``w`` and ``v`` (only takes 1, 2, 3 as possible
  800. inputs)::
  801. 1 => a @ v = w @ b @ v
  802. 2 => a @ b @ v = w @ v
  803. 3 => b @ a @ v = w @ v
  804. This keyword is ignored for standard problems.
  805. check_finite : bool, optional
  806. Whether to check that the input matrices contain only finite numbers.
  807. Disabling may give a performance gain, but may result in problems
  808. (crashes, non-termination) if the inputs do contain infinities or NaNs.
  809. subset_by_index : iterable, optional
  810. If provided, this two-element iterable defines the start and the end
  811. indices of the desired eigenvalues (ascending order and 0-indexed).
  812. To return only the second smallest to fifth smallest eigenvalues,
  813. ``[1, 4]`` is used. ``[n-3, n-1]`` returns the largest three. Only
  814. available with "evr", "evx", and "gvx" drivers. The entries are
  815. directly converted to integers via ``int()``.
  816. subset_by_value : iterable, optional
  817. If provided, this two-element iterable defines the half-open interval
  818. ``(a, b]`` that, if any, only the eigenvalues between these values
  819. are returned. Only available with "evr", "evx", and "gvx" drivers. Use
  820. ``np.inf`` for the unconstrained ends.
  821. driver : str, optional
  822. Defines which LAPACK driver should be used. Valid options are "ev",
  823. "evd", "evr", "evx" for standard problems and "gv", "gvd", "gvx" for
  824. generalized (where b is not None) problems. See the Notes section of
  825. `scipy.linalg.eigh`.
  826. turbo : bool, optional, deprecated
  827. .. deprecated:: 1.5.0
  828. 'eigvalsh' keyword argument `turbo` is deprecated in favor of
  829. ``driver=gvd`` option and will be removed in SciPy 1.12.0.
  830. eigvals : tuple (lo, hi), optional
  831. .. deprecated:: 1.5.0
  832. 'eigvalsh' keyword argument `eigvals` is deprecated in favor of
  833. `subset_by_index` option and will be removed in SciPy 1.12.0.
  834. Returns
  835. -------
  836. w : (N,) ndarray
  837. The ``N`` (``1<=N<=M``) selected eigenvalues, in ascending order, each
  838. repeated according to its multiplicity.
  839. Raises
  840. ------
  841. LinAlgError
  842. If eigenvalue computation does not converge, an error occurred, or
  843. b matrix is not definite positive. Note that if input matrices are
  844. not symmetric or Hermitian, no error will be reported but results will
  845. be wrong.
  846. See Also
  847. --------
  848. eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
  849. eigvals : eigenvalues of general arrays
  850. eigvals_banded : eigenvalues for symmetric/Hermitian band matrices
  851. eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
  852. matrices
  853. Notes
  854. -----
  855. This function does not check the input array for being Hermitian/symmetric
  856. in order to allow for representing arrays with only their upper/lower
  857. triangular parts.
  858. This function serves as a one-liner shorthand for `scipy.linalg.eigh` with
  859. the option ``eigvals_only=True`` to get the eigenvalues and not the
  860. eigenvectors. Here it is kept as a legacy convenience. It might be
  861. beneficial to use the main function to have full control and to be a bit
  862. more pythonic.
  863. Examples
  864. --------
  865. For more examples see `scipy.linalg.eigh`.
  866. >>> import numpy as np
  867. >>> from scipy.linalg import eigvalsh
  868. >>> A = np.array([[6, 3, 1, 5], [3, 0, 5, 1], [1, 5, 6, 2], [5, 1, 2, 2]])
  869. >>> w = eigvalsh(A)
  870. >>> w
  871. array([-3.74637491, -0.76263923, 6.08502336, 12.42399079])
  872. """
  873. return eigh(a, b=b, lower=lower, eigvals_only=True,
  874. overwrite_a=overwrite_a, overwrite_b=overwrite_b,
  875. turbo=turbo, eigvals=eigvals, type=type,
  876. check_finite=check_finite, subset_by_index=subset_by_index,
  877. subset_by_value=subset_by_value, driver=driver)
  878. def eigvals_banded(a_band, lower=False, overwrite_a_band=False,
  879. select='a', select_range=None, check_finite=True):
  880. """
  881. Solve real symmetric or complex Hermitian band matrix eigenvalue problem.
  882. Find eigenvalues w of a::
  883. a v[:,i] = w[i] v[:,i]
  884. v.H v = identity
  885. The matrix a is stored in a_band either in lower diagonal or upper
  886. diagonal ordered form:
  887. a_band[u + i - j, j] == a[i,j] (if upper form; i <= j)
  888. a_band[ i - j, j] == a[i,j] (if lower form; i >= j)
  889. where u is the number of bands above the diagonal.
  890. Example of a_band (shape of a is (6,6), u=2)::
  891. upper form:
  892. * * a02 a13 a24 a35
  893. * a01 a12 a23 a34 a45
  894. a00 a11 a22 a33 a44 a55
  895. lower form:
  896. a00 a11 a22 a33 a44 a55
  897. a10 a21 a32 a43 a54 *
  898. a20 a31 a42 a53 * *
  899. Cells marked with * are not used.
  900. Parameters
  901. ----------
  902. a_band : (u+1, M) array_like
  903. The bands of the M by M matrix a.
  904. lower : bool, optional
  905. Is the matrix in the lower form. (Default is upper form)
  906. overwrite_a_band : bool, optional
  907. Discard data in a_band (may enhance performance)
  908. select : {'a', 'v', 'i'}, optional
  909. Which eigenvalues to calculate
  910. ====== ========================================
  911. select calculated
  912. ====== ========================================
  913. 'a' All eigenvalues
  914. 'v' Eigenvalues in the interval (min, max]
  915. 'i' Eigenvalues with indices min <= i <= max
  916. ====== ========================================
  917. select_range : (min, max), optional
  918. Range of selected eigenvalues
  919. check_finite : bool, optional
  920. Whether to check that the input matrix contains only finite numbers.
  921. Disabling may give a performance gain, but may result in problems
  922. (crashes, non-termination) if the inputs do contain infinities or NaNs.
  923. Returns
  924. -------
  925. w : (M,) ndarray
  926. The eigenvalues, in ascending order, each repeated according to its
  927. multiplicity.
  928. Raises
  929. ------
  930. LinAlgError
  931. If eigenvalue computation does not converge.
  932. See Also
  933. --------
  934. eig_banded : eigenvalues and right eigenvectors for symmetric/Hermitian
  935. band matrices
  936. eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
  937. matrices
  938. eigvals : eigenvalues of general arrays
  939. eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
  940. eig : eigenvalues and right eigenvectors for non-symmetric arrays
  941. Examples
  942. --------
  943. >>> import numpy as np
  944. >>> from scipy.linalg import eigvals_banded
  945. >>> A = np.array([[1, 5, 2, 0], [5, 2, 5, 2], [2, 5, 3, 5], [0, 2, 5, 4]])
  946. >>> Ab = np.array([[1, 2, 3, 4], [5, 5, 5, 0], [2, 2, 0, 0]])
  947. >>> w = eigvals_banded(Ab, lower=True)
  948. >>> w
  949. array([-4.26200532, -2.22987175, 3.95222349, 12.53965359])
  950. """
  951. return eig_banded(a_band, lower=lower, eigvals_only=1,
  952. overwrite_a_band=overwrite_a_band, select=select,
  953. select_range=select_range, check_finite=check_finite)
  954. def eigvalsh_tridiagonal(d, e, select='a', select_range=None,
  955. check_finite=True, tol=0., lapack_driver='auto'):
  956. """
  957. Solve eigenvalue problem for a real symmetric tridiagonal matrix.
  958. Find eigenvalues `w` of ``a``::
  959. a v[:,i] = w[i] v[:,i]
  960. v.H v = identity
  961. For a real symmetric matrix ``a`` with diagonal elements `d` and
  962. off-diagonal elements `e`.
  963. Parameters
  964. ----------
  965. d : ndarray, shape (ndim,)
  966. The diagonal elements of the array.
  967. e : ndarray, shape (ndim-1,)
  968. The off-diagonal elements of the array.
  969. select : {'a', 'v', 'i'}, optional
  970. Which eigenvalues to calculate
  971. ====== ========================================
  972. select calculated
  973. ====== ========================================
  974. 'a' All eigenvalues
  975. 'v' Eigenvalues in the interval (min, max]
  976. 'i' Eigenvalues with indices min <= i <= max
  977. ====== ========================================
  978. select_range : (min, max), optional
  979. Range of selected eigenvalues
  980. check_finite : bool, optional
  981. Whether to check that the input matrix contains only finite numbers.
  982. Disabling may give a performance gain, but may result in problems
  983. (crashes, non-termination) if the inputs do contain infinities or NaNs.
  984. tol : float
  985. The absolute tolerance to which each eigenvalue is required
  986. (only used when ``lapack_driver='stebz'``).
  987. An eigenvalue (or cluster) is considered to have converged if it
  988. lies in an interval of this width. If <= 0. (default),
  989. the value ``eps*|a|`` is used where eps is the machine precision,
  990. and ``|a|`` is the 1-norm of the matrix ``a``.
  991. lapack_driver : str
  992. LAPACK function to use, can be 'auto', 'stemr', 'stebz', 'sterf',
  993. or 'stev'. When 'auto' (default), it will use 'stemr' if ``select='a'``
  994. and 'stebz' otherwise. 'sterf' and 'stev' can only be used when
  995. ``select='a'``.
  996. Returns
  997. -------
  998. w : (M,) ndarray
  999. The eigenvalues, in ascending order, each repeated according to its
  1000. multiplicity.
  1001. Raises
  1002. ------
  1003. LinAlgError
  1004. If eigenvalue computation does not converge.
  1005. See Also
  1006. --------
  1007. eigh_tridiagonal : eigenvalues and right eiegenvectors for
  1008. symmetric/Hermitian tridiagonal matrices
  1009. Examples
  1010. --------
  1011. >>> import numpy as np
  1012. >>> from scipy.linalg import eigvalsh_tridiagonal, eigvalsh
  1013. >>> d = 3*np.ones(4)
  1014. >>> e = -1*np.ones(3)
  1015. >>> w = eigvalsh_tridiagonal(d, e)
  1016. >>> A = np.diag(d) + np.diag(e, k=1) + np.diag(e, k=-1)
  1017. >>> w2 = eigvalsh(A) # Verify with other eigenvalue routines
  1018. >>> np.allclose(w - w2, np.zeros(4))
  1019. True
  1020. """
  1021. return eigh_tridiagonal(
  1022. d, e, eigvals_only=True, select=select, select_range=select_range,
  1023. check_finite=check_finite, tol=tol, lapack_driver=lapack_driver)
  1024. def eigh_tridiagonal(d, e, eigvals_only=False, select='a', select_range=None,
  1025. check_finite=True, tol=0., lapack_driver='auto'):
  1026. """
  1027. Solve eigenvalue problem for a real symmetric tridiagonal matrix.
  1028. Find eigenvalues `w` and optionally right eigenvectors `v` of ``a``::
  1029. a v[:,i] = w[i] v[:,i]
  1030. v.H v = identity
  1031. For a real symmetric matrix ``a`` with diagonal elements `d` and
  1032. off-diagonal elements `e`.
  1033. Parameters
  1034. ----------
  1035. d : ndarray, shape (ndim,)
  1036. The diagonal elements of the array.
  1037. e : ndarray, shape (ndim-1,)
  1038. The off-diagonal elements of the array.
  1039. select : {'a', 'v', 'i'}, optional
  1040. Which eigenvalues to calculate
  1041. ====== ========================================
  1042. select calculated
  1043. ====== ========================================
  1044. 'a' All eigenvalues
  1045. 'v' Eigenvalues in the interval (min, max]
  1046. 'i' Eigenvalues with indices min <= i <= max
  1047. ====== ========================================
  1048. select_range : (min, max), optional
  1049. Range of selected eigenvalues
  1050. check_finite : bool, optional
  1051. Whether to check that the input matrix contains only finite numbers.
  1052. Disabling may give a performance gain, but may result in problems
  1053. (crashes, non-termination) if the inputs do contain infinities or NaNs.
  1054. tol : float
  1055. The absolute tolerance to which each eigenvalue is required
  1056. (only used when 'stebz' is the `lapack_driver`).
  1057. An eigenvalue (or cluster) is considered to have converged if it
  1058. lies in an interval of this width. If <= 0. (default),
  1059. the value ``eps*|a|`` is used where eps is the machine precision,
  1060. and ``|a|`` is the 1-norm of the matrix ``a``.
  1061. lapack_driver : str
  1062. LAPACK function to use, can be 'auto', 'stemr', 'stebz', 'sterf',
  1063. or 'stev'. When 'auto' (default), it will use 'stemr' if ``select='a'``
  1064. and 'stebz' otherwise. When 'stebz' is used to find the eigenvalues and
  1065. ``eigvals_only=False``, then a second LAPACK call (to ``?STEIN``) is
  1066. used to find the corresponding eigenvectors. 'sterf' can only be
  1067. used when ``eigvals_only=True`` and ``select='a'``. 'stev' can only
  1068. be used when ``select='a'``.
  1069. Returns
  1070. -------
  1071. w : (M,) ndarray
  1072. The eigenvalues, in ascending order, each repeated according to its
  1073. multiplicity.
  1074. v : (M, M) ndarray
  1075. The normalized eigenvector corresponding to the eigenvalue ``w[i]`` is
  1076. the column ``v[:,i]``.
  1077. Raises
  1078. ------
  1079. LinAlgError
  1080. If eigenvalue computation does not converge.
  1081. See Also
  1082. --------
  1083. eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
  1084. matrices
  1085. eig : eigenvalues and right eigenvectors for non-symmetric arrays
  1086. eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
  1087. eig_banded : eigenvalues and right eigenvectors for symmetric/Hermitian
  1088. band matrices
  1089. Notes
  1090. -----
  1091. This function makes use of LAPACK ``S/DSTEMR`` routines.
  1092. Examples
  1093. --------
  1094. >>> import numpy as np
  1095. >>> from scipy.linalg import eigh_tridiagonal
  1096. >>> d = 3*np.ones(4)
  1097. >>> e = -1*np.ones(3)
  1098. >>> w, v = eigh_tridiagonal(d, e)
  1099. >>> A = np.diag(d) + np.diag(e, k=1) + np.diag(e, k=-1)
  1100. >>> np.allclose(A @ v - v @ np.diag(w), np.zeros((4, 4)))
  1101. True
  1102. """
  1103. d = _asarray_validated(d, check_finite=check_finite)
  1104. e = _asarray_validated(e, check_finite=check_finite)
  1105. for check in (d, e):
  1106. if check.ndim != 1:
  1107. raise ValueError('expected a 1-D array')
  1108. if check.dtype.char in 'GFD': # complex
  1109. raise TypeError('Only real arrays currently supported')
  1110. if d.size != e.size + 1:
  1111. raise ValueError('d (%s) must have one more element than e (%s)'
  1112. % (d.size, e.size))
  1113. select, vl, vu, il, iu, _ = _check_select(
  1114. select, select_range, 0, d.size)
  1115. if not isinstance(lapack_driver, str):
  1116. raise TypeError('lapack_driver must be str')
  1117. drivers = ('auto', 'stemr', 'sterf', 'stebz', 'stev')
  1118. if lapack_driver not in drivers:
  1119. raise ValueError('lapack_driver must be one of %s, got %s'
  1120. % (drivers, lapack_driver))
  1121. if lapack_driver == 'auto':
  1122. lapack_driver = 'stemr' if select == 0 else 'stebz'
  1123. func, = get_lapack_funcs((lapack_driver,), (d, e))
  1124. compute_v = not eigvals_only
  1125. if lapack_driver == 'sterf':
  1126. if select != 0:
  1127. raise ValueError('sterf can only be used when select == "a"')
  1128. if not eigvals_only:
  1129. raise ValueError('sterf can only be used when eigvals_only is '
  1130. 'True')
  1131. w, info = func(d, e)
  1132. m = len(w)
  1133. elif lapack_driver == 'stev':
  1134. if select != 0:
  1135. raise ValueError('stev can only be used when select == "a"')
  1136. w, v, info = func(d, e, compute_v=compute_v)
  1137. m = len(w)
  1138. elif lapack_driver == 'stebz':
  1139. tol = float(tol)
  1140. internal_name = 'stebz'
  1141. stebz, = get_lapack_funcs((internal_name,), (d, e))
  1142. # If getting eigenvectors, needs to be block-ordered (B) instead of
  1143. # matrix-ordered (E), and we will reorder later
  1144. order = 'E' if eigvals_only else 'B'
  1145. m, w, iblock, isplit, info = stebz(d, e, select, vl, vu, il, iu, tol,
  1146. order)
  1147. else: # 'stemr'
  1148. # ?STEMR annoyingly requires size N instead of N-1
  1149. e_ = empty(e.size+1, e.dtype)
  1150. e_[:-1] = e
  1151. stemr_lwork, = get_lapack_funcs(('stemr_lwork',), (d, e))
  1152. lwork, liwork, info = stemr_lwork(d, e_, select, vl, vu, il, iu,
  1153. compute_v=compute_v)
  1154. _check_info(info, 'stemr_lwork')
  1155. m, w, v, info = func(d, e_, select, vl, vu, il, iu,
  1156. compute_v=compute_v, lwork=lwork, liwork=liwork)
  1157. _check_info(info, lapack_driver + ' (eigh_tridiagonal)')
  1158. w = w[:m]
  1159. if eigvals_only:
  1160. return w
  1161. else:
  1162. # Do we still need to compute the eigenvalues?
  1163. if lapack_driver == 'stebz':
  1164. func, = get_lapack_funcs(('stein',), (d, e))
  1165. v, info = func(d, e, w, iblock, isplit)
  1166. _check_info(info, 'stein (eigh_tridiagonal)',
  1167. positive='%d eigenvectors failed to converge')
  1168. # Convert block-order to matrix-order
  1169. order = argsort(w)
  1170. w, v = w[order], v[:, order]
  1171. else:
  1172. v = v[:, :m]
  1173. return w, v
  1174. def _check_info(info, driver, positive='did not converge (LAPACK info=%d)'):
  1175. """Check info return value."""
  1176. if info < 0:
  1177. raise ValueError('illegal value in argument %d of internal %s'
  1178. % (-info, driver))
  1179. if info > 0 and positive:
  1180. raise LinAlgError(("%s " + positive) % (driver, info,))
  1181. def hessenberg(a, calc_q=False, overwrite_a=False, check_finite=True):
  1182. """
  1183. Compute Hessenberg form of a matrix.
  1184. The Hessenberg decomposition is::
  1185. A = Q H Q^H
  1186. where `Q` is unitary/orthogonal and `H` has only zero elements below
  1187. the first sub-diagonal.
  1188. Parameters
  1189. ----------
  1190. a : (M, M) array_like
  1191. Matrix to bring into Hessenberg form.
  1192. calc_q : bool, optional
  1193. Whether to compute the transformation matrix. Default is False.
  1194. overwrite_a : bool, optional
  1195. Whether to overwrite `a`; may improve performance.
  1196. Default is False.
  1197. check_finite : bool, optional
  1198. Whether to check that the input matrix contains only finite numbers.
  1199. Disabling may give a performance gain, but may result in problems
  1200. (crashes, non-termination) if the inputs do contain infinities or NaNs.
  1201. Returns
  1202. -------
  1203. H : (M, M) ndarray
  1204. Hessenberg form of `a`.
  1205. Q : (M, M) ndarray
  1206. Unitary/orthogonal similarity transformation matrix ``A = Q H Q^H``.
  1207. Only returned if ``calc_q=True``.
  1208. Examples
  1209. --------
  1210. >>> import numpy as np
  1211. >>> from scipy.linalg import hessenberg
  1212. >>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]])
  1213. >>> H, Q = hessenberg(A, calc_q=True)
  1214. >>> H
  1215. array([[ 2. , -11.65843866, 1.42005301, 0.25349066],
  1216. [ -9.94987437, 14.53535354, -5.31022304, 2.43081618],
  1217. [ 0. , -1.83299243, 0.38969961, -0.51527034],
  1218. [ 0. , 0. , -3.83189513, 1.07494686]])
  1219. >>> np.allclose(Q @ H @ Q.conj().T - A, np.zeros((4, 4)))
  1220. True
  1221. """
  1222. a1 = _asarray_validated(a, check_finite=check_finite)
  1223. if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]):
  1224. raise ValueError('expected square matrix')
  1225. overwrite_a = overwrite_a or (_datacopied(a1, a))
  1226. # if 2x2 or smaller: already in Hessenberg
  1227. if a1.shape[0] <= 2:
  1228. if calc_q:
  1229. return a1, eye(a1.shape[0])
  1230. return a1
  1231. gehrd, gebal, gehrd_lwork = get_lapack_funcs(('gehrd', 'gebal',
  1232. 'gehrd_lwork'), (a1,))
  1233. ba, lo, hi, pivscale, info = gebal(a1, permute=0, overwrite_a=overwrite_a)
  1234. _check_info(info, 'gebal (hessenberg)', positive=False)
  1235. n = len(a1)
  1236. lwork = _compute_lwork(gehrd_lwork, ba.shape[0], lo=lo, hi=hi)
  1237. hq, tau, info = gehrd(ba, lo=lo, hi=hi, lwork=lwork, overwrite_a=1)
  1238. _check_info(info, 'gehrd (hessenberg)', positive=False)
  1239. h = numpy.triu(hq, -1)
  1240. if not calc_q:
  1241. return h
  1242. # use orghr/unghr to compute q
  1243. orghr, orghr_lwork = get_lapack_funcs(('orghr', 'orghr_lwork'), (a1,))
  1244. lwork = _compute_lwork(orghr_lwork, n, lo=lo, hi=hi)
  1245. q, info = orghr(a=hq, tau=tau, lo=lo, hi=hi, lwork=lwork, overwrite_a=1)
  1246. _check_info(info, 'orghr (hessenberg)', positive=False)
  1247. return h, q
  1248. def cdf2rdf(w, v):
  1249. """
  1250. Converts complex eigenvalues ``w`` and eigenvectors ``v`` to real
  1251. eigenvalues in a block diagonal form ``wr`` and the associated real
  1252. eigenvectors ``vr``, such that::
  1253. vr @ wr = X @ vr
  1254. continues to hold, where ``X`` is the original array for which ``w`` and
  1255. ``v`` are the eigenvalues and eigenvectors.
  1256. .. versionadded:: 1.1.0
  1257. Parameters
  1258. ----------
  1259. w : (..., M) array_like
  1260. Complex or real eigenvalues, an array or stack of arrays
  1261. Conjugate pairs must not be interleaved, else the wrong result
  1262. will be produced. So ``[1+1j, 1, 1-1j]`` will give a correct result,
  1263. but ``[1+1j, 2+1j, 1-1j, 2-1j]`` will not.
  1264. v : (..., M, M) array_like
  1265. Complex or real eigenvectors, a square array or stack of square arrays.
  1266. Returns
  1267. -------
  1268. wr : (..., M, M) ndarray
  1269. Real diagonal block form of eigenvalues
  1270. vr : (..., M, M) ndarray
  1271. Real eigenvectors associated with ``wr``
  1272. See Also
  1273. --------
  1274. eig : Eigenvalues and right eigenvectors for non-symmetric arrays
  1275. rsf2csf : Convert real Schur form to complex Schur form
  1276. Notes
  1277. -----
  1278. ``w``, ``v`` must be the eigenstructure for some *real* matrix ``X``.
  1279. For example, obtained by ``w, v = scipy.linalg.eig(X)`` or
  1280. ``w, v = numpy.linalg.eig(X)`` in which case ``X`` can also represent
  1281. stacked arrays.
  1282. .. versionadded:: 1.1.0
  1283. Examples
  1284. --------
  1285. >>> import numpy as np
  1286. >>> X = np.array([[1, 2, 3], [0, 4, 5], [0, -5, 4]])
  1287. >>> X
  1288. array([[ 1, 2, 3],
  1289. [ 0, 4, 5],
  1290. [ 0, -5, 4]])
  1291. >>> from scipy import linalg
  1292. >>> w, v = linalg.eig(X)
  1293. >>> w
  1294. array([ 1.+0.j, 4.+5.j, 4.-5.j])
  1295. >>> v
  1296. array([[ 1.00000+0.j , -0.01906-0.40016j, -0.01906+0.40016j],
  1297. [ 0.00000+0.j , 0.00000-0.64788j, 0.00000+0.64788j],
  1298. [ 0.00000+0.j , 0.64788+0.j , 0.64788-0.j ]])
  1299. >>> wr, vr = linalg.cdf2rdf(w, v)
  1300. >>> wr
  1301. array([[ 1., 0., 0.],
  1302. [ 0., 4., 5.],
  1303. [ 0., -5., 4.]])
  1304. >>> vr
  1305. array([[ 1. , 0.40016, -0.01906],
  1306. [ 0. , 0.64788, 0. ],
  1307. [ 0. , 0. , 0.64788]])
  1308. >>> vr @ wr
  1309. array([[ 1. , 1.69593, 1.9246 ],
  1310. [ 0. , 2.59153, 3.23942],
  1311. [ 0. , -3.23942, 2.59153]])
  1312. >>> X @ vr
  1313. array([[ 1. , 1.69593, 1.9246 ],
  1314. [ 0. , 2.59153, 3.23942],
  1315. [ 0. , -3.23942, 2.59153]])
  1316. """
  1317. w, v = _asarray_validated(w), _asarray_validated(v)
  1318. # check dimensions
  1319. if w.ndim < 1:
  1320. raise ValueError('expected w to be at least 1D')
  1321. if v.ndim < 2:
  1322. raise ValueError('expected v to be at least 2D')
  1323. if v.ndim != w.ndim + 1:
  1324. raise ValueError('expected eigenvectors array to have exactly one '
  1325. 'dimension more than eigenvalues array')
  1326. # check shapes
  1327. n = w.shape[-1]
  1328. M = w.shape[:-1]
  1329. if v.shape[-2] != v.shape[-1]:
  1330. raise ValueError('expected v to be a square matrix or stacked square '
  1331. 'matrices: v.shape[-2] = v.shape[-1]')
  1332. if v.shape[-1] != n:
  1333. raise ValueError('expected the same number of eigenvalues as '
  1334. 'eigenvectors')
  1335. # get indices for each first pair of complex eigenvalues
  1336. complex_mask = iscomplex(w)
  1337. n_complex = complex_mask.sum(axis=-1)
  1338. # check if all complex eigenvalues have conjugate pairs
  1339. if not (n_complex % 2 == 0).all():
  1340. raise ValueError('expected complex-conjugate pairs of eigenvalues')
  1341. # find complex indices
  1342. idx = nonzero(complex_mask)
  1343. idx_stack = idx[:-1]
  1344. idx_elem = idx[-1]
  1345. # filter them to conjugate indices, assuming pairs are not interleaved
  1346. j = idx_elem[0::2]
  1347. k = idx_elem[1::2]
  1348. stack_ind = ()
  1349. for i in idx_stack:
  1350. # should never happen, assuming nonzero orders by the last axis
  1351. assert (i[0::2] == i[1::2]).all(),\
  1352. "Conjugate pair spanned different arrays!"
  1353. stack_ind += (i[0::2],)
  1354. # all eigenvalues to diagonal form
  1355. wr = zeros(M + (n, n), dtype=w.real.dtype)
  1356. di = range(n)
  1357. wr[..., di, di] = w.real
  1358. # complex eigenvalues to real block diagonal form
  1359. wr[stack_ind + (j, k)] = w[stack_ind + (j,)].imag
  1360. wr[stack_ind + (k, j)] = w[stack_ind + (k,)].imag
  1361. # compute real eigenvectors associated with real block diagonal eigenvalues
  1362. u = zeros(M + (n, n), dtype=numpy.cdouble)
  1363. u[..., di, di] = 1.0
  1364. u[stack_ind + (j, j)] = 0.5j
  1365. u[stack_ind + (j, k)] = 0.5
  1366. u[stack_ind + (k, j)] = -0.5j
  1367. u[stack_ind + (k, k)] = 0.5
  1368. # multipy matrices v and u (equivalent to v @ u)
  1369. vr = einsum('...ij,...jk->...ik', v, u).real
  1370. return wr, vr