L iE/BddlZddlmZddlmZddlZddlmZmZddlm Z ddl m Z m Z ddl mZmZmZdd lmZdd lmZmZdd lmZdd lmZmZmZmZgd Zej:dDcic]6}|dj=dDcgc]}ej>||s|c}8c}}Z d6dZ!dZ"e dd d7dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*e dd d8dZ+ d9d Z, d:d!Z-e d"d#d$dd%Z.e dd d;d&Z/dd+Z3d>d,Z4e dd d?d-Z5d.e5_6e dddddd/d0Z7e d d@d1Z8e d2 dAd3Z9 d| }$| j.|$z j.}tj@|$}%|%jC}&|&dk(r|&n|&|%jEz }n|dk(r|r | j.n| } tj>| d%tj>| dtj>| d})}(}'t%d&| | f\}*}+},|*|'|(|)\}'}(})}-}.}t;| ||+|'|(|)|-|.| |'\}}t;| ||,|'|(|)|-|.|\}}n |dk(rt%d(| | f\}/}0tjFd| z|zdzjdf|/j}||| d d d f<|/| ||| d |)\}}1}}t;| ||0| |||1|\}}n|dvrD|d*k(}tI| | |||+\}}t;| |t%d,| | f}2|2| |rd-nd./\}}n:t%d0| | f\}3}4|4| | |||1\}}}t;| ||3||\}}t;| ||||r|jK}|S)2a Solve the equation ``a @ x = b`` for ``x``, where `a` is a square matrix. If the data matrix is known to be a particular type then supplying the corresponding string to ``assume_a`` key chooses the dedicated solver. The available options are ============================= ================================ diagonal 'diagonal' tridiagonal 'tridiagonal' banded 'banded' upper triangular 'upper triangular' lower triangular 'lower triangular' symmetric 'symmetric' (or 'sym') hermitian 'hermitian' (or 'her') symmetric positive definite 'positive definite' (or 'pos') general 'general' (or 'gen') ============================= ================================ Parameters ---------- a : (N, N) array_like Square input data b : (N, NRHS) array_like Input data for the right hand side. lower : bool, default: False Ignored unless ``assume_a`` is one of ``'sym'``, ``'her'``, or ``'pos'``. If True, the calculation uses only the data in the lower triangle of `a`; entries above the diagonal are ignored. If False (default), the calculation uses only the data in the upper triangle of `a`; entries below the diagonal are ignored. overwrite_a : bool, default: False Allow overwriting data in `a` (may enhance performance). overwrite_b : bool, default: False Allow overwriting data in `b` (may enhance performance). check_finite : bool, default: True Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. assume_a : str, optional Valid entries are described above. If omitted or ``None``, checks are performed to identify structure so the appropriate solver can be called. transposed : bool, default: False If True, solve ``a.T @ x == b``. Raises `NotImplementedError` for complex `a`. Returns ------- x : (N, NRHS) ndarray The solution array. Raises ------ ValueError If size mismatches detected or input a is not square. LinAlgError If the computation fails because of matrix singularity. LinAlgWarning If an ill-conditioned input a is detected. NotImplementedError If transposed is True and input a is a complex matrix. Notes ----- If the input b matrix is a 1-D array with N elements, when supplied together with an NxN input a, it is assumed as a valid column vector despite the apparent size mismatch. This is compatible with the numpy.dot() behavior and the returned result is still 1-D array. The general, symmetric, Hermitian and positive definite solutions are obtained via calling ?GESV, ?SYSV, ?HESV, and ?POSV routines of LAPACK respectively. The datatype of the arrays define which solver is called regardless of the values. In other words, even when the complex array entries have precisely zero imaginary parts, the complex solver will be called based on the data type of the array. Examples -------- Given `a` and `b`, solve for `x`: >>> import numpy as np >>> a = np.array([[3, 2, 0], [1, -1, 0], [0, 5, 1]]) >>> b = np.array([2, 4, -1]) >>> from scipy import linalg >>> x = linalg.solve(a, b) >>> x array([ 2., -2., 9.]) >>> np.dot(a, x) == b array([ True, True, True], dtype=bool) F check_finiterrz$Input a needs to be a square matrix.z2Input b has to have same number of rows as input arEr>NT>Npositive definitegenherpossymbandedr:r4r8r9r7r5r6z% is not a recognized matrix structure>rMr8r9NNfFr.fdIzWscipy.linalg.solve can currently not solve a^T x = b or a^H x = b for complex matrices.1r4r7rP>r5r6>rLr:)gecongetrfgetrs overwrite_a)trans overwrite_b)norm)heconhesv hesv_lwork)lworklowerr[r])rc>rOr9)syconsysv sysv_lwork)gttrfgttrsgtcon)r])gbsvgbcon overwrite_abr]r5)rcr]r\trconLU)uplo)poconposv)rcr[r])&rrr_ensure_dtype_cdszr;r r+sizerr<eyer>ones empty_likendim iscomplexobjrDcharr NotImplementedError_matrix_norm_diagonal_matrix_norm_tridiagonalrT _to_banded_matrix_norm_banded_matrix_norm_triangular_matrix_norm_generalinfr1r diagabsminmaxzeros_solve_triangularravel)5r@rFrcr[r]rIassume_a transposedb_is_1Da1b1r,dtrArBr.r\r^anorma2abr-r/rWrXrYluipvtxr_r`hesv_lwrbrdresysv_lwdiag_a abs_diag_adiag_mindlrTdu_gttrf_gttrs_gtcondu2ipivrkrlpiv_trconrsrts5 r0rrLsHG &qu= >B &qu= >B B 'FB  A3R!3K3R!3K xx{bhhqk!?@@BHHQKQ277a<'( ( ww!| 266!288,bggarxx.H I O O}}Rr** ww!| 6D!GBAtGBTTH:%JKLL''0C!GW%;B%?"'7  xx}} 4 4 ??2 %'>? ? :%b,7 ] "(r<@ X ,3O9R='7AS4QBD1 t ) )/1?ACR JtWw51 Ru',-8-8:D!T QBe59 t ) )/1?ACR JtWw51 Ru',-8-8:D!T QBe59 t Z  TTF]  VVF^ >>#$Mx*..:J/J ] "RTTRGGBORWWR^RWWR^rA!12MPRTVx!X%+B2%6"Ar3dQQCr{K4QRBT59 t X &'82r(C e XXqy7*Q. r2c~|jd}||zdz}tj||f|j}tj|||<t d|dzD]"}tj|||||z |df<$t d|dzD]$}tj|| |||zd| f<&|S)NrrrJ)r;r<rr>rrange)rArBr@r,rowsris r0rrs  A W q D 4)177 +B''!*BwK 1gk ", ggam7Q;?, 1gk ".!wwq1"~7Q;! . Ir2ctj|tjtjs d|DStjtj}tj j dkr#|rtjntjnDtj j dk\r"|rtjntjfd|DS)Nc3ZK|]#}|jtj%ywr)astyper<float64).0arrays r0 z%_ensure_dtype_cdsz..s=U RZZ(=s)+ @c3DK|]}|jdyw)FcopyN)r)rrr>s r0rz%_ensure_dtype_cdsz..s @ELLUL + @s ) r< result_typer=inexactr?finfobits complex64float32 complex128r)arrayscomplexr>s @r0rurus NNF #E == +=f==mmE2#5#56G xxr! ' RZZ %   #!( bjj @ @@r2ct||}t||}t|jdk7s|jd|jdk7r td|jd|jdk7r&td|jd|jd|jdk(rkt t jd|j t jd|j j} t j|| S|xs t||}t||||||\} } | S) a Solve the equation ``a @ x = b`` for ``x``, where `a` is a triangular matrix. Parameters ---------- a : (M, M) array_like A triangular matrix b : (M,) or (M, N) array_like Right-hand side matrix in ``a x = b`` lower : bool, optional Use only data contained in the lower triangle of `a`. Default is to use upper triangle. trans : {0, 1, 2, 'N', 'T', 'C'}, optional Type of system to solve: ======== ========= trans system ======== ========= 0 or 'N' a x = b 1 or 'T' a^T x = b 2 or 'C' a^H x = b ======== ========= unit_diagonal : bool, optional If True, diagonal elements of `a` are assumed to be 1 and will not be referenced. overwrite_b : bool, optional Allow overwriting data in `b` (may enhance performance) check_finite : bool, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Returns ------- x : (M,) or (M, N) ndarray Solution to the system ``a x = b``. Shape of return matches `b`. Raises ------ LinAlgError If `a` is singular Notes ----- .. versionadded:: 0.9.0 Examples -------- Solve the lower triangular system a x = b, where:: [3 0 0 0] [4] a = [2 1 0 0] b = [2] [1 0 1 0] [4] [1 1 1 1] [2] >>> import numpy as np >>> from scipy.linalg import solve_triangular >>> a = np.array([[3, 0, 0, 0], [2, 1, 0, 0], [1, 0, 1, 0], [1, 1, 1, 1]]) >>> b = np.array([4, 2, 4, 2]) >>> x = solve_triangular(a, b, lower=True) >>> x array([ 1.33333333, -0.66666667, 2.66666667, -1.33333333]) >>> a.dot(x) # Check the result array([ 4., 2., 4., 2.]) rHrErrexpected square matrixz shapes of a  and b  are incompatiblerJ) rlenr;r+rvrr<rwr>rxryr r) r@rFr\rc unit_diagonalr]rIrr dt_nonemptyr_s r0rrsL AL 9B AL 9B 288}RXXa[BHHQK7122 xx{bhhqk!<z BSTUU ww!|& FF1BHH %rwwq'A % }}R{333R!3K RUE=+ NDAq Hr2c@ddddj||}td||f\}|jjs|dk(r|||||||\}}n||j||| | |\}}|dk(r||fS|dkDrt d|dz t d| d ) NrrrE)NrC)trtrs)r]rcr\unitdiagz/singular matrix: resolution failed at diagonal illegal value in z-th argument of internal trtrs)getr flags f_contiguousrr r+) rrr\rcrr]rrr-s r0rrs!! $ ( ( 6E j2r( 3FE xx BKu#m=4bkU"'i-A4 qy$w axKDQRF8TUU ($/MN OOr2c 0|\}}t|||||||S)a Solve the equation ``a @ x = b`` for ``x``, where ``a`` is the banded matrix defined by `ab`. The matrix a is stored in `ab` using the matrix diagonal ordered form:: ab[u + i - j, j] == a[i,j] Example of `ab` (shape of a is (6,6), `u` =1, `l` =2):: * a01 a12 a23 a34 a45 a00 a11 a22 a33 a44 a55 a10 a21 a32 a43 a54 * a20 a31 a42 a53 * * Parameters ---------- (l, u) : (integer, integer) Number of non-zero lower and upper diagonals ab : (`l` + `u` + 1, M) array_like Banded matrix b : (M,) or (M, K) array_like Right-hand side overwrite_ab : bool, optional Discard data in `ab` (may enhance performance) overwrite_b : bool, optional Discard data in `b` (may enhance performance) check_finite : bool, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Returns ------- x : (M,) or (M, K) ndarray The solution to the system a x = b. Returned shape depends on the shape of `b`. Examples -------- Solve the banded system a x = b, where:: [5 2 -1 0 0] [0] [1 4 2 -1 0] [1] a = [0 1 3 2 -1] b = [2] [0 0 1 2 2] [2] [0 0 0 1 1] [3] There is one nonzero diagonal below the main diagonal (l = 1), and two above (u = 2). The diagonal banded form of the matrix is:: [* * -1 -1 -1] ab = [* 2 2 2 2] [5 4 3 2 1] [1 1 1 1 *] >>> import numpy as np >>> from scipy.linalg import solve_banded >>> ab = np.array([[0, 0, -1, -1, -1], ... [0, 2, 2, 2, 2], ... [5, 4, 3, 2, 1], ... [1, 1, 1, 1, 0]]) >>> b = np.array([0, 1, 2, 2, 3]) >>> x = solve_banded((1, 2), ab, b) >>> x array([-2.37288136, 3.93220339, -4. , 4.3559322 , -1.3559322 ]) )rnr]rI) _solve_banded)l_and_urrFrnr]rInlowernuppers r0rrs-LVV Q\%0| MMr2)rr)rr)rrEc bt||d}t||d}|jd|jdk7r td||zdz|jdk7r%td||zdzd|jdd |jdk(rkt t j d|j t jd|j j} t j|| S|xs t||}|jddk(r$t j|| } | ||dfz} | S||cxk(rdk(rTnnQ|xs t||}td ||f\} |dddf} |dddf} |d ddf}| || | |||||\}} } }}ngtd||f\}t jd |z|zdz|jdf|j }|||dddf<|||||d|\}}}}|dk(r|S|dkDr tdtd| d)NT)rI as_inexactrgr&shapes of ab and b are not compatible.rzCinvalid values for the number of lower and upper diagonals: l+u+1 (z) does not equal ab.shape[0] ()rJr)gtsvrE)rkrmsingular matrixrz"-th argument of internal gbsv/gtsv)rr;r+rvrr<rwr>rxryr rr rr )rrrrFrnr]rIrrrb2rrrTrrrr-rkrrrs r0rr_s[ B\d KB ALT JB xx|rxx{"ABB bhhqk)!#$$B288A;-q R   ww!| 266!288,bggarxx.H I O O}}Rr**3R!3K xx|q XXbK 1 bm  1#:{2r':  RH5 12Y q!tH 3B3Z"2q"b, #/>QAt!RH5 XXqx&(1,bhhqk:$** M67A:BT,79CD qy ax+,, ($/QR SSr2cPt||}t||}|jd|jdk7r td|jdk(rkt t j d|jt jd|jj}t j||S|xs t||}|xs t||}|jddk(rltd||f\} |r|dd d fj} |dd df} n*|dd d fj} |ddd fj} | | | ||||\} } } }n!td ||f\}|||||| \}} }|dkDrt|d |dkrtd | d| S)a Solve the equation ``a @ x = b`` for ``x``, where ``a`` is the Hermitian positive-definite banded matrix defined by `ab`. Uses Thomas' Algorithm, which is more efficient than standard LU factorization, but should only be used for Hermitian positive-definite matrices. The matrix ``a`` is stored in `ab` either in lower diagonal or upper diagonal ordered form: ab[u + i - j, j] == a[i,j] (if upper form; i <= j) ab[ i - j, j] == a[i,j] (if lower form; i >= j) Example of `ab` (shape of ``a`` is (6, 6), number of upper diagonals, ``u`` =2):: upper form: * * a02 a13 a24 a35 * a01 a12 a23 a34 a45 a00 a11 a22 a33 a44 a55 lower form: a00 a11 a22 a33 a44 a55 a10 a21 a32 a43 a54 * a20 a31 a42 a53 * * Cells marked with * are not used. Parameters ---------- ab : (``u`` + 1, M) array_like Banded matrix b : (M,) or (M, K) array_like Right-hand side overwrite_ab : bool, optional Discard data in `ab` (may enhance performance) overwrite_b : bool, optional Discard data in `b` (may enhance performance) lower : bool, optional Is the matrix in the lower form. (Default is upper form) check_finite : bool, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Returns ------- x : (M,) or (M, K) ndarray The solution to the system ``a x = b``. Shape of return matches shape of `b`. Notes ----- In the case of a non-positive definite matrix ``a``, the solver `solve_banded` may be used. Examples -------- Solve the banded system ``A x = b``, where:: [ 4 2 -1 0 0 0] [1] [ 2 5 2 -1 0 0] [2] A = [-1 2 6 2 -1 0] b = [2] [ 0 -1 2 7 2 -1] [3] [ 0 0 -1 2 8 2] [3] [ 0 0 0 -1 2 9] [3] >>> import numpy as np >>> from scipy.linalg import solveh_banded ``ab`` contains the main diagonal and the nonzero diagonals below the main diagonal. That is, we use the lower form: >>> ab = np.array([[ 4, 5, 6, 7, 8, 9], ... [ 2, 2, 2, 2, 2, 0], ... [-1, -1, -1, -1, 0, 0]]) >>> b = np.array([1, 2, 2, 3, 3, 3]) >>> x = solveh_banded(ab, b, lower=True) >>> x array([ 0.03431373, 0.45938375, 0.05602241, 0.47759104, 0.17577031, 0.34733894]) Solve the Hermitian banded system ``H x = b``, where:: [ 8 2-1j 0 0 ] [ 1 ] H = [2+1j 5 1j 0 ] b = [1+1j] [ 0 -1j 9 -2-1j] [1-2j] [ 0 0 -2+1j 6 ] [ 0 ] In this example, we put the upper diagonals in the array ``hb``: >>> hb = np.array([[0, 2-1j, 1j, -2-1j], ... [8, 5, 9, 6 ]]) >>> b = np.array([1, 1+1j, 1-2j, 0]) >>> x = solveh_banded(hb, b) >>> x array([ 0.07318536-0.02939412j, 0.11877624+0.17696461j, 0.10077984-0.23035393j, -0.00479904-0.09358128j]) rHrgrrrrJrE)ptsvN)pbsv)rcrnr]z&th leading minor not positive definiterzth argument of internal pbsv)rr;r+rvrr<rwr>rxryr r realconjr )rrFrnr]rcrIrrrrrTerrr-rcs r0rrsR B\ :B AL 9B xx|rxx{"ABB ww!| 266!288,bggarxx.H I O O}}Rr**3R!3K6;r2#6L xx{a RH5 1a4 A1crc6 A1a4 A1ab5  AaB l)+2q$!RH5"bL&13 1d axTF"HIJJ ax,dUG3OPQQ Hr2cvt|tr|n|tj|f\}}t ||||S)a Solve the equation ``T @ x = b`` for ``x``, where ``T`` is a Toeplitz matrix defined by `c_or_cr`. The Toeplitz matrix has constant diagonals, with ``c`` as its first column and ``r`` as its first row. If ``r`` is not given, ``r == conjugate(c)`` is assumed. .. warning:: Beginning in SciPy 1.17, multidimensional input will be treated as a batch, not ``ravel``\ ed. To preserve the existing behavior, ``ravel`` arguments before passing them to `solve_toeplitz`. Parameters ---------- c_or_cr : array_like or tuple of (array_like, array_like) The vector ``c``, or a tuple of arrays (``c``, ``r``). If not supplied, ``r = conjugate(c)`` is assumed; in this case, if c[0] is real, the Toeplitz matrix is Hermitian. r[0] is ignored; the first row of the Toeplitz matrix is ``[c[0], r[1:]]``. b : (M,) or (M, K) array_like Right-hand side in ``T x = b``. check_finite : bool, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (result entirely NaNs) if the inputs do contain infinities or NaNs. Returns ------- x : (M,) or (M, K) ndarray The solution to the system ``T @ x = b``. Shape of return matches shape of `b`. See Also -------- toeplitz : Toeplitz matrix Notes ----- The solution is computed using Levinson-Durbin recursion, which is faster than generic least-squares methods, but can be less numerically stable. Examples -------- Solve the Toeplitz system ``T @ x = b``, where:: [ 1 -1 -2 -3] [1] T = [ 3 1 -1 -2] b = [2] [ 6 3 1 -1] [2] [10 6 3 1] [5] To specify the Toeplitz matrix, only the first column and the first row are needed. >>> import numpy as np >>> c = np.array([1, 3, 6, 10]) # First column of T >>> r = np.array([1, -1, -2, -3]) # First row of T >>> b = np.array([1, 2, 2, 5]) >>> from scipy.linalg import solve_toeplitz, toeplitz >>> x = solve_toeplitz((c, r), b) >>> x array([ 1.66666667, -1. , -2.66666667, 2.33333333]) Check the result by creating the full Toeplitz matrix and multiplying it by ``x``. We should get `b`. >>> T = toeplitz(c, r) >>> T.dot(x) array([ 1., 2., 2., 5.]) ) isinstancetupler< conjugate_solve_toeplitz)c_or_crrFrIrrs r0rrs8X!%07w W@U6VDAq 1aL 11r2c t||f||d\}}}}}|jdk(rtj|Stj|ddd|f}| t d|j dk(r$t|tj|\}}|Stjt|jdD cgc]+} t|tj|dd| fd-c} }|j|}|Scc} w)NT) keep_b_shaperrgz)illegal value, `b` is a required argumentr) _validate_args_for_toeplitz_opsrvr<ry concatenater+rzrascontiguousarray column_stackrr;reshape) rrrFrIr>b_shapevalsrrrs r0rrqs= A>1R"W:q/ *DyDEEvv{b221561 H OO&+AGGAJ&79!"&dB,@,@1a4,IJ1M9 : AIIw  H 9s0D c|}|dkr||jz }d|cxkr|jkrnn|j|Std|d)Nr'zaxis' entry is out of bounds)rzr;r+)anamer@axisaxs r0 _get_axis_lenr sO B Av aff Bwwr{ q;< ==r2crtj|}td||}tj|}td||}||k7r&td|jd|jd|j dk(rkt tjd|jtjd|jj} tj|| Stjjtj||d d } tj| } ||| jd |ztjtj j"z}|jd k7r|jd z|_ntj|}| |k} tj$| } | r|d k(r t'dd| | <tjjtj||d d }|| z }| r#tj(|t*| z}d||<tjj-|d }tj.|s!tj.|s |j0}|d k7rtj|d |}|S)aSolve the equation ``C @ x = b`` for ``x``, where ``C`` is a circulant matrix defined by `c`. `C` is the circulant matrix associated with the vector `c`. The system is solved by doing division in Fourier space. The calculation is:: x = ifft(fft(b) / fft(c)) where `fft` and `ifft` are the fast Fourier transform and its inverse, respectively. For a large vector `c`, this is *much* faster than solving the system with the full circulant matrix. Parameters ---------- c : array_like The coefficients of the circulant matrix. b : array_like Right-hand side matrix in ``a x = b``. singular : str, optional This argument controls how a near singular circulant matrix is handled. If `singular` is "raise" and the circulant matrix is near singular, a `LinAlgError` is raised. If `singular` is "lstsq", the least squares solution is returned. Default is "raise". tol : float, optional If any eigenvalue of the circulant matrix has an absolute value that is less than or equal to `tol`, the matrix is considered to be near singular. If not given, `tol` is set to:: tol = abs_eigs.max() * abs_eigs.size * np.finfo(np.float64).eps where `abs_eigs` is the array of absolute values of the eigenvalues of the circulant matrix. caxis : int When `c` has dimension greater than 1, it is viewed as a collection of circulant vectors. In this case, `caxis` is the axis of `c` that holds the vectors of circulant coefficients. baxis : int When `b` has dimension greater than 1, it is viewed as a collection of vectors. In this case, `baxis` is the axis of `b` that holds the right-hand side vectors. outaxis : int When `c` or `b` are multidimensional, the value returned by `solve_circulant` is multidimensional. In this case, `outaxis` is the axis of the result that holds the solution vectors. Returns ------- x : ndarray Solution to the system ``C x = b``. Raises ------ LinAlgError If the circulant matrix associated with `c` is near singular. See Also -------- circulant : circulant matrix Notes ----- For a 1-D vector `c` with length `m`, and an array `b` with shape ``(m, ...)``, solve_circulant(c, b) returns the same result as solve(circulant(c), b) where `solve` and `circulant` are from `scipy.linalg`. .. versionadded:: 0.16.0 Examples -------- >>> import numpy as np >>> from scipy.linalg import solve_circulant, solve, circulant, lstsq >>> c = np.array([2, 2, 4]) >>> b = np.array([1, 2, 3]) >>> solve_circulant(c, b) array([ 0.75, -0.25, 0.25]) Compare that result to solving the system with `scipy.linalg.solve`: >>> solve(circulant(c), b) array([ 0.75, -0.25, 0.25]) A singular example: >>> c = np.array([1, 1, 0, 0]) >>> b = np.array([1, 2, 3, 4]) Calling ``solve_circulant(c, b)`` will raise a `LinAlgError`. For the least square solution, use the option ``singular='lstsq'``: >>> solve_circulant(c, b, singular='lstsq') array([ 0.25, 1.25, 2.25, 1.25]) Compare to `scipy.linalg.lstsq`: >>> x, resid, rnk, s = lstsq(circulant(c), b) >>> x array([ 0.25, 1.25, 2.25, 1.25]) A broadcasting example: Suppose we have the vectors of two circulant matrices stored in an array with shape (2, 5), and three `b` vectors stored in an array with shape (3, 5). For example, >>> c = np.array([[1.5, 2, 3, 0, 0], [1, 1, 4, 3, 2]]) >>> b = np.arange(15).reshape(-1, 5) We want to solve all combinations of circulant matrices and `b` vectors, with the result stored in an array with shape (2, 3, 5). When we disregard the axes of `c` and `b` that hold the vectors of coefficients, the shapes of the collections are (2,) and (3,), respectively, which are not compatible for broadcasting. To have a broadcast result with shape (2, 3), we add a trivial dimension to `c`: ``c[:, np.newaxis, :]`` has shape (2, 1, 5). The last dimension holds the coefficients of the circulant matrices, so when we call `solve_circulant`, we can use the default ``caxis=-1``. The coefficients of the `b` vectors are in the last dimension of the array `b`, so we use ``baxis=-1``. If we use the default `outaxis`, the result will have shape (5, 2, 3), so we'll use ``outaxis=-1`` to put the solution vectors in the last dimension. >>> x = solve_circulant(c[:, np.newaxis, :], b, baxis=-1, outaxis=-1) >>> x.shape (2, 3, 5) >>> np.set_printoptions(precision=3) # For compact output of numbers. >>> x array([[[-0.118, 0.22 , 1.277, -0.142, 0.302], [ 0.651, 0.989, 2.046, 0.627, 1.072], [ 1.42 , 1.758, 2.816, 1.396, 1.841]], [[ 0.401, 0.304, 0.694, -0.867, 0.377], [ 0.856, 0.758, 1.149, -0.412, 0.831], [ 1.31 , 1.213, 1.603, 0.042, 1.286]]]) Check by solving one pair of `c` and `b` vectors (cf. ``x[1, 1, :]``): >>> solve_circulant(c[1], b[1, :]) array([ 0.856, 0.758, 1.149, -0.412, 0.831]) rrFz Shapes of c rrrr(rJrgr)rraiseznear singular circulant matrix.r)r<rr r+r;rvraranger>rxryfftmoveaxisrrrrepsanyr ones_likeboolifftr{r)rrFsingulartolcaxisbaxisoutaxisncnbrfcabs_fc near_zerosis_near_singularfbqmaskrs r0rrs"l aA sAu %B aA sAu %B Rx<yy@QRSS vv{ RYYq8WWQagg688= }}Qb)) BKK5"-B 7B VVBZF {jjbj!B&"**)=)A)AA 99? D(CI--$C3Jvvj) w ?@ @BzN BKK5"-B 7B RA ||AT*Z7$  AB A OOA "//!"4 FF"} KK2w ' Hr2cvt||}t|jdk7s|jd|jdk7r td|jdk(rKt t jd|jj}t j||S|xs t||}td|f\}}}|||\}} } | dk(r6t||jd} td | z} ||| | d \} } | dkDr td | dkrtd | d  S)a Compute the inverse of a matrix. Parameters ---------- a : array_like Square matrix to be inverted. overwrite_a : bool, optional Discard data in `a` (may improve performance). Default is False. check_finite : bool, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Returns ------- ainv : ndarray Inverse of the matrix `a`. Raises ------ LinAlgError If `a` is singular. ValueError If `a` is not square, or not 2D. Examples -------- >>> import numpy as np >>> from scipy import linalg >>> a = np.array([[1., 2.], [3., 4.]]) >>> linalg.inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> np.dot(a, linalg.inv(a)) array([[ 1., 0.], [ 0., 1.]]) rHrErrrrJ)rXgetri getri_lworkrZg)\(?)rb overwrite_lurrz$-th argument of internal getrf|getri)rrr;r+rvrr<rwr>ryr r r intr ) r@r[rIrrrXr&r'rrr-rbinv_as r0rr_s>R AL 9B 288}RXXa[BHHQK7122 ww!| * + 1 1}}Rr**3R!3K 02A24!8E5+"+6MBT qy{BHHQK8D5L!B5qA t ax+,, axw&J K   Lr2cv|rtj|ntj|}|jdkr t d|j d|j dk7rt d|j d|j jdvrXt|j j}|s#td|j jd |j|d }d }t|j d k(rs|j jd vrtjntj}|jdk(r|d Stj|j dd|S|j dddk(rn|d}|jd k(r|d}|j jdvr|S|j jdk(r|jdS|jdSt!||s|s|j#d}|j$dr|j$ds|j#d}|jdk(rJt'|}tj(|rtj|Stj|S|j j}|dvr|j+rdnd}tj,|j dd|}t/|j ddDcgc] }t1|c}D]}t'||||<|Scc}w)a Compute the determinant of a matrix The determinant is a scalar that is a function of the associated square matrix coefficients. The determinant value is zero for singular matrices. Parameters ---------- a : (..., M, M) array_like Input array to compute determinants for. overwrite_a : bool, optional Allow overwriting data in a (may enhance performance). check_finite : bool, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Returns ------- det : (...) float or complex Determinant of `a`. For stacked arrays, a scalar is returned for each (m, m) slice in the last two dimensions of the input. For example, an input of shape (p, q, m, m) will produce a result of shape (p, q). If all dimensions are 1 a scalar is returned regardless of ndim. Notes ----- The determinant is computed by performing an LU factorization of the input with LAPACK routine 'getrf', and then calculating the product of diagonal entries of the U factor. Even if the input array is single precision (float32 or complex64), the result will be returned in double precision (float64 or complex128) to prevent overflows. Examples -------- >>> import numpy as np >>> from scipy import linalg >>> a = np.array([[1,2,3], [4,5,6], [7,8,9]]) # A singular matrix >>> linalg.det(a) 0.0 >>> b = np.array([[0,2,3], [4,5,6], [7,8,9]]) >>> linalg.det(b) 3.0 >>> # An array with the shape (3, 2, 2, 2) >>> c = np.array([[[[1., 2.], [3., 4.]], ... [[5., 6.], [7., 8.]]], ... [[[9., 10.], [11., 12.]], ... [[13., 14.], [15., 16.]]], ... [[[17., 18.], [19., 20.]], ... [[21., 22.], [23., 24.]]]]) >>> linalg.det(c) # The resulting shape is (3, 2) array([[-2., -2.], [-2., -2.], [-2., -2.]]) >>> linalg.det(c[0, 0]) # Confirm the (0, 0) slice, [[1, 2], [3, 4]] -2.0 rEz1The input array must be at least two-dimensional.rgzALast 2 dimensions of the array must be square but received shape .r%z The dtype "z6" cannot be cast to float(32, 64) or complex(64, 128).rTFD?N)r;r>)rr).rrr dDrSrTDr)order C_CONTIGUOUS WRITEABLErRrJ)r<rasarrayrzr+r;r>r|lapack_cast_dict TypeErrornamerrrrrxr rrr isrealobjisloweremptyrr) r@r[rIr dtype_chardtyprrinds r0rrs~%1  a bjjmB ww{LMM xx|rxx|#002z<= = xx}}F"%bhhmm4 k"((--9DDE EYYz!} %  BHH~XX]]$6rzzBMM 77a<9 77#2d; ; xx}  ] 77a<BB 88==D I!##!5ryy~I299S>I r1 s#B HH^ $+)> WW3W  ww!|r"#%<<#4 3M"--:LMJT&..0Sc ((288CR= 3C288CR=9aq9:-#BsG,C- J:sL6c &t||}t||}t|jdk7r td|j\} } t|jdk(r|jd} nd} | |jdk7rtd| d|jdd| dk(s| dk(rt j | f|jdd zt j || } | dk(r%tjj|d dz} nt jd } | | dt jd fS|}|tj}|d vrtd|dt||df||f\}}|jjdk(rdnd}| | krot|jdk(r/t j | | f|j }||d | d d f<n&t j | |j }||d | |}|xs t||}|xs t||}|)t j |jj"}|dvr |dk(r%t%|| | | |}|||||||\}} }}}}nT|dk(rO|r&t%|| | | |\}}||||||dd\} }}}n't%|| | | |\}}}|||||||dd\} }}}dkDr t'd|dkrtd| d|t j(g j }| | kDr<| d | }| k(r0t j*t j,| | d dzd }|} | |fS|dk(rt%|| | | |}t j |jddftj. }||||||dd\}} }}}|dkrtd| d| | kDr| d | }|} | t j0g| j|d fSy )a  Compute least-squares solution to the equation ``a @ x = b``. Compute a vector x such that the 2-norm ``|b - A x|`` is minimized. Parameters ---------- a : (M, N) array_like Left-hand side array b : (M,) or (M, K) array_like Right hand side array cond : float, optional Cutoff for 'small' singular values; used to determine effective rank of a. Singular values smaller than ``cond * largest_singular_value`` are considered zero. overwrite_a : bool, optional Discard data in `a` (may enhance performance). Default is False. overwrite_b : bool, optional Discard data in `b` (may enhance performance). Default is False. check_finite : bool, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. lapack_driver : str, optional Which LAPACK driver is used to solve the least-squares problem. Options are ``'gelsd'``, ``'gelsy'``, ``'gelss'``. Default (``'gelsd'``) is a good choice. However, ``'gelsy'`` can be slightly faster on many problems. ``'gelss'`` was used historically. It is generally slow but uses less memory. .. versionadded:: 0.17.0 Returns ------- x : (N,) or (N, K) ndarray Least-squares solution. residues : (K,) ndarray or float Square of the 2-norm for each column in ``b - a x``, if ``M > N`` and ``rank(A) == n`` (returns a scalar if ``b`` is 1-D). Otherwise a (0,)-shaped array is returned. rank : int Effective rank of `a`. s : (min(M, N),) ndarray or None Singular values of `a`. The condition number of ``a`` is ``s[0] / s[-1]``. Raises ------ LinAlgError If computation does not converge. ValueError When parameters are not compatible. See Also -------- scipy.optimize.nnls : linear least squares with non-negativity constraint Notes ----- When ``'gelsy'`` is used as a driver, `residues` is set to a (0,)-shaped array and `s` is always ``None``. Examples -------- >>> import numpy as np >>> from scipy.linalg import lstsq >>> import matplotlib.pyplot as plt Suppose we have the following data: >>> x = np.array([1, 2.5, 3.5, 4, 5, 7, 8.5]) >>> y = np.array([0.3, 1.1, 1.5, 2.0, 3.2, 6.6, 8.6]) We want to fit a quadratic polynomial of the form ``y = a + b*x**2`` to this data. We first form the "design matrix" M, with a constant column of 1s and a column containing ``x**2``: >>> M = x[:, np.newaxis]**[0, 2] >>> M array([[ 1. , 1. ], [ 1. , 6.25], [ 1. , 12.25], [ 1. , 16. ], [ 1. , 25. ], [ 1. , 49. ], [ 1. , 72.25]]) We want to find the least-squares solution to ``M.dot(p) = y``, where ``p`` is a vector with length 2 that holds the parameters ``a`` and ``b``. >>> p, res, rnk, s = lstsq(M, y) >>> p array([ 0.20925829, 0.12013861]) Plot the data and the fitted curve. >>> plt.plot(x, y, 'o', label='data') >>> xx = np.linspace(0, 9, 101) >>> yy = p[0] + p[1]*xx**2 >>> plt.plot(xx, yy, label='least squares fit, $y = a + bx^2$') >>> plt.xlabel('x') >>> plt.ylabel('y') >>> plt.legend(framealpha=1, shadow=True) >>> plt.grid(alpha=0.25) >>> plt.show() rHrEzInput array a should be 2Drrz=Shape mismatch: a and b should have the same number of rows (z != z).NrJr )r)gelsdgelsygelsszLAPACK driver "z" is not found_lworkrSTF)rBr@rB)r[r]r@z,SVD did not converge in Linear Least Squaresrz-th argument of internal rAz-th argument of internal gelsy)rrr;r+r<r common_typelinalgr^r;rdefault_lapack_driverr r>rCr rrr r r5sumrint32r)r@rFcondr[r]rI lapack_driverrrmr,nrhsrresiduesdriver lapack_func lapack_lwork real_datarrbvsrankworkr-iworkrworkresidsx1jptvjs r0rr-so` AL 9B AL 9B 288}566 88DAq 288}xx{BHHQK&&'SRXXa[M=> >Ava HHaTBHHQRL(r20F G 6yy~~bq~114Hxx~H(Arxx~-- F ~,, 00?6(.ABB 0&4:861B2D24b!;K%**//36UI1u rxx=A 1d);+<+<=BBrr1uI!;#4#45BBrF 3R!3K3R!3K |xx ))*.. ## W "<AtTBE(3BD%@K@K)M %Aq!T4w -lAq$M u#.r2u/4dE5$J 1dD'5\1a594'A#ue#.r2ueU/3UE$C 1dD !8LM M !8#TE7*CM?S Bagg. q52ABqyqu q 0q9A&$!! 7 |Q4>xx!a(9)"b$*/?1at !80$7UVW W q52ABA"((2qww't33 r2r@)atolrtol return_rankrIc(t||}tj|dd\}}}|jjj }t j|d} |dn|}|5t|jt j|jzn|}|dks|dkr td|| |zz} t j|| kD} |ddd| f}||d| z}||d| zjj} |r| | fS| S)aI Compute the (Moore-Penrose) pseudo-inverse of a matrix. Calculate a generalized inverse of a matrix using its singular-value decomposition ``U @ S @ V`` in the economy mode and picking up only the columns/rows that are associated with significant singular values. If ``s`` is the maximum singular value of ``a``, then the significance cut-off value is determined by ``atol + rtol * s``. Any singular value below this value is assumed insignificant. Parameters ---------- a : (M, N) array_like Matrix to be pseudo-inverted. atol : float, optional Absolute threshold term, default value is 0. .. versionadded:: 1.7.0 rtol : float, optional Relative threshold term, default value is ``max(M, N) * eps`` where ``eps`` is the machine precision value of the datatype of ``a``. .. versionadded:: 1.7.0 return_rank : bool, optional If True, return the effective rank of the matrix. check_finite : bool, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Returns ------- B : (N, M) ndarray The pseudo-inverse of matrix `a`. rank : int The effective rank of the matrix. Returned if `return_rank` is True. Raises ------ LinAlgError If SVD computation does not converge. See Also -------- pinvh : Moore-Penrose pseudoinverse of a hermitian matrix. Notes ----- If ``A`` is invertible then the Moore-Penrose pseudoinverse is exactly the inverse of ``A`` [1]_. If ``A`` is not invertible then the Moore-Penrose pseudoinverse computes the ``x`` solution to ``Ax = b`` such that ``||Ax - b||`` is minimized [1]_. References ---------- .. [1] Penrose, R. (1956). On best approximate solutions of linear matrix equations. Mathematical Proceedings of the Cambridge Philosophical Society, 52(1), 17-19. doi:10.1017/S0305004100030929 Examples -------- Given an ``m x n`` matrix ``A`` and an ``n x m`` matrix ``B`` the four Moore-Penrose conditions are: 1. ``ABA = A`` (``B`` is a generalized inverse of ``A``), 2. ``BAB = B`` (``A`` is a generalized inverse of ``B``), 3. ``(AB)* = AB`` (``AB`` is hermitian), 4. ``(BA)* = BA`` (``BA`` is hermitian) [1]_. Here, ``A*`` denotes the conjugate transpose. The Moore-Penrose pseudoinverse is a unique ``B`` that satisfies all four of these conditions and exists for any ``A``. Note that, unlike the standard matrix inverse, ``A`` does not have to be a square matrix or have linearly independent columns/rows. As an example, we can calculate the Moore-Penrose pseudoinverse of a random non-square matrix and verify it satisfies the four conditions. >>> import numpy as np >>> from scipy import linalg >>> rng = np.random.default_rng() >>> A = rng.standard_normal((9, 6)) >>> B = linalg.pinv(A) >>> np.allclose(A @ B @ A, A) # Condition 1 True >>> np.allclose(B @ A @ B, B) # Condition 2 True >>> np.allclose((A @ B).conj().T, A @ B) # Condition 3 True >>> np.allclose((B @ A).conj().T, B @ A) # Condition 4 True rHF) full_matricesrIinitialN&atol and rtol values must be positive.)rrsvdr>r|rcr<rr;rrr+rGrr) r@r\r]r^rIurSvhtmaxSvalrTBs r0rrsH 1<8AqEJHAq"  A 66!R D24D.2l3qww<"((1+// )D r tbyABB  C 66!c'?D !UdU( A5DMA RY  A$wr2cHt||}tj||dd\}}|jjj }t jt j|d} |dn|}|5t|jt j|jzn|}|dks|dkr td|| |zz} t|| kD} d || z } |dd| f}|| z|jjz} |r | t| fS| S) au Compute the (Moore-Penrose) pseudo-inverse of a Hermitian matrix. Calculate a generalized inverse of a complex Hermitian/real symmetric matrix using its eigenvalue decomposition and including all eigenvalues with 'large' absolute value. Parameters ---------- a : (N, N) array_like Real symmetric or complex hermetian matrix to be pseudo-inverted atol : float, optional Absolute threshold term, default value is 0. .. versionadded:: 1.7.0 rtol : float, optional Relative threshold term, default value is ``N * eps`` where ``eps`` is the machine precision value of the datatype of ``a``. .. versionadded:: 1.7.0 lower : bool, optional Whether the pertinent array data is taken from the lower or upper triangle of `a`. (Default: lower) return_rank : bool, optional If True, return the effective rank of the matrix. check_finite : bool, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Returns ------- B : (N, N) ndarray The pseudo-inverse of matrix `a`. rank : int The effective rank of the matrix. Returned if `return_rank` is True. Raises ------ LinAlgError If eigenvalue algorithm does not converge. See Also -------- pinv : Moore-Penrose pseudoinverse of a matrix. Examples -------- For a more detailed example see `pinv`. >>> import numpy as np >>> from scipy.linalg import pinvh >>> rng = np.random.default_rng() >>> a = rng.standard_normal((9, 6)) >>> a = np.dot(a, a.T) >>> B = pinvh(a) >>> np.allclose(a, a @ B @ a) True >>> np.allclose(B, B @ a @ B) True rHFev)rcrIrNrarbNrdr/)rreighr>r|rcr<rrr;rrr+rrr)r@r\r]rcr^rIrSrfrhrirj above_cutoff psigma_diagrks r0r r xsJ 1<8A <<U4 HDAq  A 66"&&)R (D24D.2l3qww<"((1+// )D r tbyABB  CFSLL,'K !\/A [AFFHJJ&A#k"""r2)ArEctjt|d}tj|js t d|j dk(rttjd|j\}}tj||j}|rDtj|t|}tjt|} ||| ffS|tj||jfStd|f} | |||| \}} } } }|dkrt d | d tj| t}| | | d z|| | d z| j!t"d d z } |jd}tj|} | |kr;t%| | d zddddd D] \}}||z |k(r| ||z |g| |||z g<"| dkDr(t%| d| D]\}}||k(r | ||g| ||g<|r||| ffStj| }tj||| <|tj&||ddffS)a# Compute a diagonal similarity transformation for row/column balancing. The balancing tries to equalize the row and column 1-norms by applying a similarity transformation such that the magnitude variation of the matrix entries is reflected to the scaling matrices. Moreover, if enabled, the matrix is first permuted to isolate the upper triangular parts of the matrix and, again if scaling is also enabled, only the remaining subblocks are subjected to scaling. Parameters ---------- A : (n, n) array_like Square data matrix for the balancing. permute : bool, optional The selector to define whether permutation of A is also performed prior to scaling. scale : bool, optional The selector to turn on and off the scaling. If False, the matrix will not be scaled. separate : bool, optional This switches from returning a full matrix of the transformation to a tuple of two separate 1-D permutation and scaling arrays. overwrite_a : bool, optional This is passed to xGEBAL directly. Essentially, overwrites the result to the data. It might increase the space efficiency. See LAPACK manual for details. This is False by default. Returns ------- B : (n, n) ndarray Balanced matrix T : (n, n) ndarray A possibly permuted diagonal matrix whose nonzero entries are integer powers of 2 to avoid numerical truncation errors. scale, perm : (n,) ndarray If ``separate`` keyword is set to True then instead of the array ``T`` above, the scaling and the permutation vectors are given separately as a tuple without allocating the full array ``T``. Notes ----- The balanced matrix satisfies the following equality .. math:: B = T^{-1} A T The scaling coefficients are approximated to the nearest power of 2 to avoid round-off errors. This algorithm is particularly useful for eigenvalue and matrix decompositions and in many cases it is already called by various LAPACK routines. The algorithm is based on the well-known technique of [1]_ and has been modified to account for special cases. See [2]_ for details which have been implemented since LAPACK v3.5.0. Before this version there are corner cases where balancing can actually worsen the conditioning. See [3]_ for such examples. The code is a wrapper around LAPACK's xGEBAL routine family for matrix balancing. .. versionadded:: 0.19.0 References ---------- .. [1] B.N. Parlett and C. Reinsch, "Balancing a Matrix for Calculation of Eigenvalues and Eigenvectors", Numerische Mathematik, Vol.13(4), 1969, :doi:`10.1007/BF02165404` .. [2] R. James, J. Langou, B.R. Lowery, "On matrix balancing and eigenvector computation", 2014, :arxiv:`1401.5766` .. [3] D.S. Watkins. A case where balancing is harmful. Electron. Trans. Numer. Anal, Vol.23, 2006. Examples -------- >>> import numpy as np >>> from scipy import linalg >>> x = np.array([[1,2,0], [9,1,0.01], [1,2,10*np.pi]]) >>> y, permscale = linalg.matrix_balance(x) >>> np.abs(x).sum(axis=0) / np.abs(x).sum(axis=1) array([ 3.66666667, 0.4995005 , 0.91312162]) >>> np.abs(y).sum(axis=0) / np.abs(y).sum(axis=1) array([ 1.2 , 1.27041742, 0.92658316]) # may vary >>> permscale # only powers of 2 (0.5 == 2^(-1)) array([[ 0.5, 0. , 0. ], # may vary [ 0. , 1. , 0. ], [ 0. , 0. , 1. ]]) TrHz/The data matrix for balancing should be square.rrErJr;gebal)scalepermuter[zHxGEBAL exited with the internal error "illegal value in argument number z8.". See LAPACK documentation for the xGEBAL error codes.rFrNrg)r<rrequalr;r+rvr!rwr>ryrrrr floatrr) enumerater)rqrvruseparater[b_nt_nrkscalingpermrtlohipsr-r,r>riperms r0r!r!s}F (>?A 88QWW JKK vv{!"&&!''":;S MM!399 - ll1CF3G99SV$Dwo% %"--333 g -E,79Ar2r4 ax>?CeWELLM M ll2U+G"RT{GBr!t 3U #a 'B  A 99Qd}t j |td|j}|j}| tdt||}|j}|jd|jdk7} |r| s|jd|jdk7r tdtj|xs,tj|xstj|} | rtjntj fd |||fD\}}}|jdk(r|s|jd d}n?|jdk7r0|j|jd|j dkDrd nd}||| |fS) aValidate arguments and format inputs for toeplitz functions Parameters ---------- c_or_cr : array_like or tuple of (array_like, array_like) The vector ``c``, or a tuple of arrays (``c``, ``r``). Whatever the actual shape of ``c``, it will be converted to a 1-D array. If not supplied, ``r = conjugate(c)`` is assumed; in this case, if c[0] is real, the Toeplitz matrix is Hermitian. r[0] is ignored; the first row of the Toeplitz matrix is ``[c[0], r[1:]]``. Whatever the actual shape of ``r``, it will be converted to a 1-D array. b : (M,) or (M, K) array_like Right-hand side in ``T x = b``. check_finite : bool Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (result entirely NaNs) if the inputs do contain infinities or NaNs. keep_b_shape : bool Whether to convert a (M,) dimensional b into a (M, 1) dimensional matrix. enforce_square : bool, optional If True (default), this verifies that the Toeplitz matrix is square. Returns ------- r : array 1d array corresponding to the first row of the Toeplitz matrix. c: array 1d array corresponding to the first column of the Toeplitz matrix. b: array (M,), (M, 1) or (M, K) dimensional array, post validation, corresponding to ``b``. dtype: numpy datatype ``dtype`` stores the datatype of ``r``, ``c`` and ``b``. If any of ``r``, ``c`` or ``b`` are complex, ``dtype`` is ``np.complex128``, otherwise, it is ``np.float``. b_shape: tuple Shape of ``b`` after passing it through ``_asarray_validated``. rHrzBeginning in SciPy 1.17, multidimensional input will be treated as a batch, not `ravel`ed. To preserve the existing behavior and silence this warning, `ravel` arguments before passing them to `toeplitz`, `matmul_toeplitz`, and `solve_toeplitz`.rEr)z`b` must be an array, not None.rzIncompatible dimensions.c3LK|]}tj|yw)rJN)r<r5)rrr>s r0rz2_validate_args_for_toeplitz_ops..s=arzz!5))=s!$rg)rrrrrzwarningsr FutureWarningrr+r;r<r{rrrrv) rrFrIrenforce_squarerrmsgr is_not_squareis_cmplxr>s @r0rrqsV'5!1 q| < q| < w\ B KKMvvzQVVaZF  c=Q7 GGI GGIy:;;1<8AggGGGAJ!''!*,M=QWWQZ1771:-E344q!MR__Q%7M2??1;MH%BMM2::E=Aq!9=GAq!vv{< IIb!  1 IIaggaj " : aE7 ""r2cddlm}m}m}m}t |||dd\}} }} } |j \} } t | }t |}||zdz }t | dk(r|fn|| f}|jdk(rtj||Stj| |dddf}tj|stj|r?||d| jdd}|||d| }|||zd| d |d d f}n?||d| jdd}|||d| }|||zd|| d |d d f}|j|S) a Efficient Toeplitz Matrix-Matrix Multiplication using FFT This function returns the matrix multiplication between a Toeplitz matrix and a dense matrix. The Toeplitz matrix has constant diagonals, with c as its first column and r as its first row. If r is not given, ``r == conjugate(c)`` is assumed. .. warning:: Beginning in SciPy 1.17, multidimensional input will be treated as a batch, not ``ravel``\ ed. To preserve the existing behavior, ``ravel`` arguments before passing them to `matmul_toeplitz`. Parameters ---------- c_or_cr : array_like or tuple of (array_like, array_like) The vector ``c``, or a tuple of arrays (``c``, ``r``). If not supplied, ``r = conjugate(c)`` is assumed; in this case, if c[0] is real, the Toeplitz matrix is Hermitian. r[0] is ignored; the first row of the Toeplitz matrix is ``[c[0], r[1:]]``. x : (M,) or (M, K) array_like Matrix with which to multiply. check_finite : bool, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (result entirely NaNs) if the inputs do contain infinities or NaNs. workers : int, optional To pass to scipy.fft.fft and ifft. Maximum number of workers to use for parallel computation. If negative, the value wraps around from ``os.cpu_count()``. See scipy.fft.fft for more details. Returns ------- T @ x : (M,) or (M, K) ndarray The result of the matrix multiplication ``T @ x``. Shape of return matches shape of `x`. See Also -------- toeplitz : Toeplitz matrix solve_toeplitz : Solve a Toeplitz system using Levinson Recursion Notes ----- The Toeplitz matrix is embedded in a circulant matrix and the FFT is used to efficiently calculate the matrix-matrix product. Because the computation is based on the FFT, integer inputs will result in floating point outputs. This is unlike NumPy's `matmul`, which preserves the data type of the input. This is partly based on the implementation that can be found in [1]_, licensed under the MIT license. More information about the method can be found in reference [2]_. References [3]_ and [4]_ have more reference implementations in Python. .. versionadded:: 1.6.0 References ---------- .. [1] Jacob R Gardner, Geoff Pleiss, David Bindel, Kilian Q Weinberger, Andrew Gordon Wilson, "GPyTorch: Blackbox Matrix-Matrix Gaussian Process Inference with GPU Acceleration" with contributions from Max Balandat and Ruihan Wu. Available online: https://github.com/cornellius-gp/gpytorch .. [2] J. Demmel, P. Koev, and X. Li, "A Brief Survey of Direct Linear Solvers". In Z. Bai, J. Demmel, J. Dongarra, A. Ruhe, and H. van der Vorst, editors. Templates for the Solution of Algebraic Eigenvalue Problems: A Practical Guide. SIAM, Philadelphia, 2000. Available at: http://www.netlib.org/utk/people/JackDongarra/etemplates/node384.html .. [3] R. Scheibler, E. Bezzam, I. Dokmanic, Pyroomacoustics: A Python package for audio room simulations and array processing algorithms, Proc. IEEE ICASSP, Calgary, CA, 2018. https://github.com/LCAV/pyroomacoustics/blob/pypi-release/ pyroomacoustics/adaptive/util.py .. [4] Marano S, Edwards B, Ferrari G and Fah D (2017), "Fitting Earthquake Spectra: Colored Noise and Incomplete Data", Bulletin of the Seismological Society of America., January, 2017. Vol. 107(1), pp. 276-291. Examples -------- Multiply the Toeplitz matrix T with matrix x:: [ 1 -1 -2 -3] [1 10] T = [ 3 1 -1 -2] x = [2 11] [ 6 3 1 -1] [2 11] [10 6 3 1] [5 19] To specify the Toeplitz matrix, only the first column and the first row are needed. >>> import numpy as np >>> c = np.array([1, 3, 6, 10]) # First column of T >>> r = np.array([1, -1, -2, -3]) # First row of T >>> x = np.array([[1, 10], [2, 11], [2, 11], [5, 19]]) >>> from scipy.linalg import toeplitz, matmul_toeplitz >>> matmul_toeplitz((c, r), x) array([[-20., -80.], [ -7., -8.], [ 9., 85.], [ 33., 218.]]) Check the result by creating the full Toeplitz matrix and multiplying it by ``x``. >>> toeplitz(c, r) @ x array([[-20, -80], [ -7, -8], [ 9, 85], [ 33, 218]]) The full matrix is never formed explicitly, so this routine is suitable for very large Toeplitz matrices. >>> n = 1000000 >>> matmul_toeplitz([1] + [0]*(n-1), np.ones(n)) array([1., 1., 1., ..., 1., 1., 1.], shape=(1000000,)) rE)rrrfftirfftF)rrrrrsrg)rworkers)r,rrN)rrr,) rrrrrr;rrvr<ryrr{r)rrrIrrrrrrrr>x_shaper,rKT_nrowsT_ncolsp return_shape embedded_colfft_matfft_x mat_times_xs r0r"r"s|@-,=LuULAq!UG 77DAq!fG!fG'AA!$W!2G:! L vv{}}Ql33>>1a1Rj/2L |$(:lG<DDRKAG475=q#*,,4WHaK9 |!W=EEb!LQ!!W5GEM$+q22:7(A+?  ;   --r2rQ)FFFTNF)rFFFT)rFFF)FFT)FFFT)T)rNrgrr)FT)NFFTN)NNTFT)TTFF)FN)rsd(.4::'"%33 A \\%02rww6Ga[R[[A5FGHH2 * ",8\*).9=P +P f L #   A8\*?D59X +X xCH"'P(BG"HMV=-LI/TJ/Td8\*FK#I +I XM2d 0>15/0I Z8GGX}B8\*:?+/H4+H4V&8tTxxv8;@ZZz89>$W)W)v48O#d_.E= H2s+FFF FF