
    Bpj%K                        S r SSKrSSKJrJr  SSKJr  SSKJ	r	J
r
  SSKJrJrJr  SSKJr  SS	KJr  / S
QrS r  SS jrSS jr\" S5      S 5       r\" S5      SS j5       r\" S5      SSSSS.S jj5       r\" SS5      S 5       rg)zSVD decomposition functions.    N)_apply_over_batch_deprecate_dtypes   )_batched_linalg)LinAlgError_datacopied)_normalize_lapack_dtype_ensure_aligned_and_native	HAS_ILP64)get_lapack_funcs)_asarray_validated)svdsvdvalsdiagsvdorthsubspace_angles
null_spacec           
          U  Hc  nUS   nUS   nUS:w  d  M  US:  a  [        SU S35      eUS:  d  M2  US:X  a  US:X  a  SU S	3n[        U5      e[        S
U*  SU SU S35      e   g)zAFormat/emit errors/warnings from a lowlevel batched routine.
    lapack_infonumr   z!SVD did not converge for slice = .gesddzslice z has a NaN entryzillegal value in zth argument of internal z  for slice N)r   
ValueError)err_lstlapack_driverentryinfor   msgs         T/var/www/html/pdf-tiff/venv/lib/python3.13/site-packages/scipy/linalg/_decomp_svd.py_format_emit_errors_warningsr!      s     ]#El19ax!$EcU!"LMMax G+
"3%'78C$S/) 'w.F}o"3%q*      TFr   c                    [        U[        5      (       d  [        S5      eUS;  a  SU S3n[        U5      e[	        XS9n[        SU5        UR                  S:  a  [        SUR                  < 35      eUR                  S	   UR                  S
   p[        Xs5      u  ps[        Xs5      u  psU=(       d    [        Xp5      nU=(       a%    UR                  S:H  =(       a    UR                  S   nUR                  S:X  Ga1  [        [        R                  " SUR                   S95      u  pnUR                  SS	 n[        R"                  " X}S-   UR                   S9nU(       ay  [        R"                  " X}X4-   U
R                   S9n[        R$                  " U5      US'   [        R"                  " X}X4-   UR                   S9n[        R$                  " U	5      US'   OH[        R"                  " X}US4-   U
R                   S9n[        R"                  " X}SU	4-   UR                   S9nU(       a  XU4$ U$ U(       a  X:  a  X4OX4u  nnU(       aS  [&        (       dG  UU-  [        R(                  " [        R*                  5      R,                  :  a  [        SU SU S35      eOn[-        UU-  U	U-  5      n[&        (       dQ  [-        UU-  U	U-  5      [        R(                  " [        R*                  5      R,                  :  a  [        SU S35      e[.        R0                  " XuX!U5      nUS
   nU(       a  [3        UU5        U(       a  USS
 $ US   $ )a[  
Singular Value Decomposition.

Factorizes the matrix `a` into two unitary matrices ``U`` and ``Vh``, and
a 1-D array ``s`` of singular values (real, non-negative) such that
``a == U @ S @ Vh``, where ``S`` is a suitably shaped matrix of zeros with
main diagonal ``s``.

Parameters
----------
a : (..., M, N) array_like
    Matrix to decompose.
full_matrices : bool, optional
    If True (default), `U` and `Vh` are of shape ``(M, M)``, ``(N, N)``.
    If False, the shapes are ``(M, K)`` and ``(K, N)``, where
    ``K = min(M, N)``.
compute_uv : bool, optional
    Whether to compute also ``U`` and ``Vh`` in addition to ``s``.
    Default is True.
overwrite_a : bool, optional
    Whether to overwrite data in `a` (may improve performance). Default is False.
    See :ref:`tutorial_linalg_overwrite` for details.
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.
lapack_driver : {'gesdd', 'gesvd'}, optional
    Whether to use the more efficient divide-and-conquer approach
    (``'gesdd'``) or general rectangular approach (``'gesvd'``)
    to compute the SVD. MATLAB and Octave use the ``'gesvd'`` approach.
    Default is ``'gesdd'``.

Returns
-------
U : ndarray
    Unitary matrix having left singular vectors as columns.
    Of shape ``(M, M)`` or ``(M, K)``, depending on `full_matrices`.
    Only present when ``compute_uv=True``.
s : ndarray
    The singular values, sorted in non-increasing order.
    Of shape (K,), with ``K = min(M, N)``.
Vh : ndarray
    Unitary matrix having right singular vectors as rows.
    Of shape ``(N, N)`` or ``(K, N)`` depending on `full_matrices`.
    Only present when ``compute_uv=True``.

Raises
------
LinAlgError
    If SVD computation does not converge.

See Also
--------
svdvals : Compute singular values of a matrix.
diagsvd : Construct the Sigma matrix, given the vector s.

Notes
-----
The array argument of this function, `a`, may have additional
"batch" dimensions prepended to the core shape. In this case, the array is treated
as a batch of lower-dimensional slices; see :ref:`linalg_batch` for details.

Examples
--------
>>> import numpy as np
>>> from scipy import linalg
>>> rng = np.random.default_rng()
>>> m, n = 9, 6
>>> a = rng.standard_normal((m, n)) + 1.j*rng.standard_normal((m, n))
>>> U, s, Vh = linalg.svd(a)
>>> U.shape,  s.shape, Vh.shape
((9, 9), (6,), (6, 6))

Reconstruct the original matrix from the decomposition:

>>> sigma = np.zeros((m, n))
>>> for i in range(min(m, n)):
...     sigma[i, i] = s[i]
>>> a1 = U @ sigma @ Vh
>>> np.allclose(a, a1)
True

Alternatively, use ``full_matrices=False`` (notice that the shape of
``U`` is then ``(m, n)`` instead of ``(m, m)``):

>>> U, s, Vh = linalg.svd(a, full_matrices=False)
>>> U.shape, s.shape, Vh.shape
((9, 6), (6,), (6, 6))
>>> S = np.diag(s)
>>> np.allclose(a, U @ S @ Vh)
True

>>> s2 = linalg.svd(a, compute_uv=False)
>>> np.allclose(s, s2)
True

If the input matrix has more than two dimensions, it is interpreted as a batch of
two-dimensional matrices:

>>> aa = np.stack((a, 2*a))
>>> linalg.svdvals(aa)[0] == linalg.svdvals(a)
array([ True,  True,  True,  True,  True,  True])
>>> linalg.svdvals(aa)[1] == 2 * linalg.svdvals(a)
array([ True,  True,  True,  True,  True,  True])
zlapack_driver must be a string)r   gesvdz/lapack_driver must be "gesdd" or "gesvd", not ""check_finiter      z&Expected at least ndim=2, got a1.ndim=F_CONTIGUOUSr   dtypeN)r   )shaper-   .zIndexing a matrix size z x zu would incur integer overflow in LAPACK. Instead, either use using numpy.linalg.svd or buildSciPy with ILP64 support.zIndexing a matrix of z elements would incur an in integer overflow in LAPACK. Instead, either use using numpy.linalg.svd or buildSciPy with ILP64 support.)
isinstancestr	TypeErrorr   r   r   ndimr.   r	   r
   r   flagssizer   npeyer-   
empty_likeidentityr   iinfoint32maxr   _svdr!   )afull_matrices
compute_uvoverwrite_ar'   r   messagea1mnu0s0v0batch_shapesuvmax_mnmin_mnszresr   s                         r    r   r   %   s   V mS))899..CM?RST!! 
A	9BeR 	ww{B"''DEE88B<"q .b>OB0AOB5+b"4KO277a<Obhh~6NK 
ww!|23
hhsmMM"$$6bhhGbqf(<BHHMA[[^AcFbqf(<BHHMA[[^AcFbq!f(<BHHMAbq!f(<BHHMA7NH#$5!qf9"((1C1G1G!G #:6(#fX N> "> ? ?
 QZV,B9QZV!<rxx?Q?U?U!U #8 => "> ? ?
 


:kC "gG$Wm<3Bx1vr"   c                     [        U SUUS9$ )a	  
Compute singular values of a matrix.

Parameters
----------
a : (M, N) array_like
    Matrix to decompose.
overwrite_a : bool, optional
    Whether to overwrite data in `a` (may improve performance). Default is False.
    See :ref:`tutorial_linalg_overwrite` for details.
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
-------
s : (min(M, N),) ndarray
    The singular values, sorted in decreasing order.

Raises
------
LinAlgError
    If SVD computation does not converge.

See Also
--------
svd : Compute the full singular value decomposition of a matrix.
diagsvd : Construct the Sigma matrix, given the vector s.

Notes
-----
Array argument of this function, `a`, may have additional
"batch" dimensions prepended to the core shape. In this case, the array is treated
as a batch of lower-dimensional slices; see :ref:`linalg_batch` for details.

Examples
--------
>>> import numpy as np
>>> from scipy.linalg import svdvals
>>> m = np.array([[1.0, 0.0],
...               [2.0, 3.0],
...               [1.0, 1.0],
...               [0.0, 2.0],
...               [1.0, 0.0]])
>>> svdvals(m)
array([ 4.28091555,  1.63516424])

If the input matrix has more than two dimensions, it is interpreted as a batch of
two-dimensional matrices:

>>> mm = np.stack((m, 2*m))
>>> svdvals(mm)
array([[4.28091555, 1.63516424],
       [8.56183109, 3.27032847]])

We can verify the maximum singular value of `m` by computing the maximum
length of `m @ u` over all the unit vectors `u` in the (x,y) plane.
We approximate "all" the unit vectors with a large sample. Because
of linearity, we only need the unit vectors with angles in ``[0, pi]``.

>>> t = np.linspace(0, np.pi, 2000)
>>> u = np.array([np.cos(t), np.sin(t)])
>>> np.linalg.norm(m @ u, axis=0).max()
4.2809152422538475

`p` is a projection matrix with rank 1. With exact arithmetic,
its singular values would be ``[1, 0, 0, 0]``.

>>> v = np.array([0.1, 0.3, 0.9, 0.3])
>>> p = np.outer(v, v)
>>> svdvals(p)
array([  1.00000000e+00,   2.02021698e-17,   1.56692500e-17,
         8.15115104e-34])

The singular values of an orthogonal matrix are all 1. Here, we
create a random orthogonal matrix by using the ``rvs()`` method of
`scipy.stats.ortho_group`.

>>> from scipy.stats import ortho_group
>>> orth = ortho_group.rvs(4)
>>> svdvals(orth)
array([ 1.,  1.,  1.,  1.])
r   )r?   r@   r'   )r   )r=   r@   r'   s      r    r   r      s    j qQK(* *r"   )rI   r   c                 P   [         R                  " U 5      nUR                  R                  n[	        U 5      nXQ:X  a/  [         R
                  " U[         R                  " XU-
  4US945      $ XR:X  a,  [         R                  U[         R                  " X-
  U4US94   $ [        S5      e)a'  
Construct the sigma matrix in SVD from singular values and size M, N.

Parameters
----------
s : (M,) or (N,) array_like
    Singular values
M : int
    Size of the matrix whose singular values are `s`.
N : int
    Size of the matrix whose singular values are `s`.

Returns
-------
S : (M, N) ndarray
    The S-matrix in the singular value decomposition

See Also
--------
svd : Singular value decomposition of a matrix
svdvals : Compute singular values of a matrix.

Examples
--------
>>> import numpy as np
>>> from scipy.linalg import diagsvd
>>> vals = np.array([1, 2, 3])  # The array representing the computed svd
>>> diagsvd(vals, 3, 4)
array([[1, 0, 0, 0],
       [0, 2, 0, 0],
       [0, 0, 3, 0]])
>>> diagsvd(vals, 4, 3)
array([[1, 0, 0],
       [0, 2, 0],
       [0, 0, 3],
       [0, 0, 0]])

r,   zLength of s must be M or N.)	r5   diagr-   charlenhstackzerosr_r   )rI   MNparttypMorNs         r    r   r   0  s    P 771:D
**//Cq6Dyyy$!U3 ?@AA	uuT288QUAJc::;;677r"   )Ar(   c                 H   [        U SS9u  p#nUR                  S   UR                  S   peUc6  [        R                  " UR                  5      R
                  [        XV5      -  n[        R                  " USS9U-  n[        R                  " X7:  [        S9nUSS2SU24   n	U	$ )	a  
Construct an orthonormal basis for the range of A using SVD.

Parameters
----------
A : (M, N) array_like
    Input array
rcond : float, optional
    Relative condition number. Singular values ``s`` smaller than
    ``rcond * max(s)`` are considered zero.
    Default: floating point eps * max(M,N).

Returns
-------
Q : (M, K) ndarray
    Orthonormal basis for the range of A.
    K = effective rank of A, as determined by rcond

See Also
--------
svd : Singular value decomposition of a matrix
null_space : Matrix null space

Examples
--------
>>> import numpy as np
>>> from scipy.linalg import orth
>>> A = np.array([[2, 0, 0], [0, 5, 0]])  # rank 2 array
>>> orth(A)
array([[0., 1.],
       [1., 0.]])
>>> orth(A.T)
array([[0., 1.],
       [1., 0.],
       [0., 0.]])

F)r>   r   r   N        initialr,   )
r   r.   r5   finfor-   epsr;   amaxsumint)
r]   rcondrJ   rI   vhrX   rY   tolr   Qs
             r    r   r   e  s    N 1E*HA"771:rxx{q}!%%A	1
''!R
 5
(C
&&
$C	!TcT'
AHr"   )r@   r'   r   c                z   [        U SUX4S9u  pVnUR                  S   UR                  S   pUc6  [        R                  " UR                  5      R
                  [        X5      -  n[        R                  " USS9U-  n
[        R                  " Xj:  [        S9nX{S2SS24   R                  R                  5       nU$ )	a;  
Construct an orthonormal basis for the null space of A using SVD.

Parameters
----------
A : (M, N) array_like
    Input array
rcond : float, optional
    Relative condition number. Singular values ``s`` smaller than
    ``rcond * max(s)`` are considered zero.
    Default: floating point eps * max(M,N).
overwrite_a : bool, optional
    Whether to overwrite `a`; may improve performance. Default is False.
    See :ref:`tutorial_linalg_overwrite` for details.
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.
lapack_driver : {'gesdd', 'gesvd'}, optional
    Whether to use the more efficient divide-and-conquer approach
    (``'gesdd'``) or general rectangular approach (``'gesvd'``)
    to compute the SVD. MATLAB and Octave use the ``'gesvd'`` approach.
    Default is ``'gesdd'``.

Returns
-------
Z : (N, K) ndarray
    Orthonormal basis for the null space of A.
    K = dimension of effective null space, as determined by rcond

See Also
--------
svd : Singular value decomposition of a matrix
orth : Matrix range

Examples
--------
1-D null space:

>>> import numpy as np
>>> from scipy.linalg import null_space
>>> A = np.array([[1, 1], [1, 1]])
>>> ns = null_space(A)
>>> ns * np.copysign(1, ns[0,0])  # Remove the sign ambiguity of the vector
array([[ 0.70710678],
       [-0.70710678]])

2-D null space:

>>> from numpy.random import default_rng
>>> rng = default_rng()
>>> B = rng.random((3, 5))
>>> Z = null_space(B)
>>> Z.shape
(5, 2)
>>> np.allclose(B.dot(Z), 0)
True

The basis vectors are orthonormal (up to rounding error):

>>> Z.T.dot(Z)
array([[  1.00000000e+00,   6.92087741e-17],
       [  6.92087741e-17,   1.00000000e+00]])

T)r>   r@   r'   r   r   r   Nr_   r`   r,   )r   r.   r5   rb   r-   rc   r;   rd   re   rf   Tconj)r]   rg   r@   r'   r   rJ   rI   rh   rX   rY   ri   r   rj   s                r    r   r     s    H 1Dk ,KHA"771:rxx{q}!%%A	1
''!R
 5
(C
&&
$C
46
AHr"   )Br(   c                 .   [        U SS9n [        U R                  5      S:w  a  [        SU R                   35      e[	        U 5      nA [        USS9n[        UR                  5      S:w  a  [        SUR                   35      e[        U5      [        U5      :w  a+  [        SUR                  S    SUR                  S    35      e[	        U5      nA[
        R                  " UR                  R                  5       U5      n[        U5      nUR                  S   UR                  S   :  a  U[
        R                  " X$5      -
  nO1U[
        R                  " X4R                  R                  5       5      -
  nAAAUS-  S	:  nUR                  5       (       a5  [
        R                  " [
        R                  " [        USS
9SS5      5      nOSn[
        R                  " Xg[
        R                  " [
        R                  " USSS2   SS5      5      5      nU$ )a  
Compute the subspace angles between two matrices.

Parameters
----------
A : (M, N) array_like
    The first input array.
B : (M, K) array_like
    The second input array.

Returns
-------
angles : ndarray, shape (min(N, K),)
    The subspace angles between the column spaces of `A` and `B` in
    descending order.

See Also
--------
orth
svd

Notes
-----
This computes the subspace angles according to the formula
provided in [1]_. For equivalence with MATLAB and Octave behavior,
use ``angles[0]``.

.. versionadded:: 1.0

References
----------
.. [1] Knyazev A, Argentati M (2002) Principal Angles between Subspaces
       in an A-Based Scalar Product: Algorithms and Perturbation
       Estimates. SIAM J. Sci. Comput. 23:2008-2040.

Examples
--------
A Hadamard matrix, which has orthogonal columns, so we expect that
the subspace angle to be :math:`\frac{\pi}{2}`:

>>> import numpy as np
>>> from scipy.linalg import hadamard, subspace_angles
>>> rng = np.random.default_rng()
>>> H = hadamard(4)
>>> print(H)
[[ 1  1  1  1]
 [ 1 -1  1 -1]
 [ 1  1 -1 -1]
 [ 1 -1 -1  1]]
>>> np.rad2deg(subspace_angles(H[:, :2], H[:, 2:]))
array([ 90.,  90.])

And the subspace angle of a matrix to itself should be zero:

>>> subspace_angles(H[:, :2], H[:, :2]) <= 2 * np.finfo(float).eps
array([ True,  True], dtype=bool)

The angles between non-orthogonal subspaces are in between these extremes:

>>> x = rng.standard_normal((4, 3))
>>> np.rad2deg(subspace_angles(x[:, :2], x[:, [2]]))
array([ 55.832])  # random
Tr&   r(   zexpected 2D array, got shape z/A and B must have the same number of rows, got r   z and r   g      ?)r@   g      g      ?r_   Nr*   )r   rT   r.   r   r   r5   dotrl   rm   r   anyarcsinclipwherearccos)	r]   rn   QAQBQA_H_QBsigmamask	mu_arcsinthetas	            r    r   r     s   H 	140A
177|q8	BCC	aB	140A
177|q8	BCC
1vRJHHQK=aggaj\; < 	<	aB	 ffRTTYY["%GGE 
xx{bhhqk!$$IINN,--
B A:DxxzzIIbgggaT&BCLM		
 HHTbiiddS"0M&NOELr"   )TTFTr   )FT)N)__doc__numpyr5   scipy._lib._utilr   r    r   _miscr   r   lapackr	   r
   r   scipy.linalg.lapackr   _decompr   __all__r!   r   r   r   r   r   r    r"   r    <module>r      s    "  A  , R R 0 ' Q( =B)0odV*r 8/8 /8h 8- -` 8KU$K K\ 8X&h 'hr"   