
    e!hYb                        d dl Z d dlmZ d dlZd dlmZmZmZmZm	Z	m
Z
mZmZmZmZmZmZ d dlmZmZ ddlmZ ddlmZmZ ddlmZ dd	lmZmZ dd
lmZm Z  ddl!m"Z" ddl#m$Z$m%Z% ddl&m'Z' g dZ( ejR                  d      jT                  Z* ejR                  d      jT                  Z+ddd dd ddZ,d Z-d!dZ.d Z/d"dZ0d Z1d Z2d Z3d Z4d Z5d Z6d Z7d Z8d"dZ9d"dZ:d  Z;y)#    N)product)dotdiagprodlogical_notravel	transpose	conjugateabsoluteamaxsignisfinitetriu)LinAlgError	bandwidth   )norm)solveinv)svd)schurrsf2csf)expm_frechet	expm_cond)sqrtm)pick_pade_structurepade_UV_calc)_funm_loops)expmcosmsinmtanmcoshmsinhmtanhmlogmfunmsignmr   fractional_matrix_powerr   r   
khatri_raodf)ilr,   r+   FDc                     t        j                  |       } t        | j                        dk7  s| j                  d   | j                  d   k7  rt	        d      | S )a  
    Wraps asarray with the extra requirement that the input be a square matrix.

    The motivation is that the matfuncs module has real functions that have
    been lifted to square matrix functions.

    Parameters
    ----------
    A : array_like
        A square matrix.

    Returns
    -------
    out : ndarray
        An ndarray copy or view or other representation of A.

       r   r   z expected square array_like input)npasarraylenshape
ValueErrorAs    ^/var/www/html/diagnosisapp-backend/venv/lib/python3.12/site-packages/scipy/linalg/_matfuncs.py_asarray_squarer;   $   sI    $ 	

1A
177|qAGGAJ!''!*4;<<H    c                    t        j                  |       rvt        j                  |      ra|1t        dz  t        dz  dt
        |j                  j                        }t        j                  |j                  d|      r|j                  }|S )a(  
    Return either B or the real part of B, depending on properties of A and B.

    The motivation is that B has been computed as a complicated function of A,
    and B may be perturbed by negligible imaginary components.
    If A is real and B is complex with small imaginary components,
    then return a real copy of B.  The assumption in that case would be that
    the imaginary components of B are numerical artifacts.

    Parameters
    ----------
    A : ndarray
        Input array whose type is to be checked as real vs. complex.
    B : ndarray
        Array to be returned, possibly without its imaginary part.
    tol : float
        Absolute tolerance.

    Returns
    -------
    out : real or complex array
        Either the input array B or only the real part of the input array B.

         @@g    .Ar   r           )atol)r3   	isrealobjiscomplexobjfepseps_array_precisiondtypecharallcloseimagreal)r9   Btols      r:   _maybe_realrN   <   sf    4 
||A2??1-;3h3s7+,<QWW\\,JKC;;qvvs-AHr<   c                 l    t        |       } ddl}|j                  j                  j	                  | |      S )a  
    Compute the fractional power of a matrix.

    Proceeds according to the discussion in section (6) of [1]_.

    Parameters
    ----------
    A : (N, N) array_like
        Matrix whose fractional power to evaluate.
    t : float
        Fractional power.

    Returns
    -------
    X : (N, N) array_like
        The fractional power of the matrix.

    References
    ----------
    .. [1] Nicholas J. Higham and Lijing lin (2011)
           "A Schur-Pade Algorithm for Fractional Powers of a Matrix."
           SIAM Journal on Matrix Analysis and Applications,
           32 (3). pp. 1056-1078. ISSN 0895-4798

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import fractional_matrix_power
    >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
    >>> b = fractional_matrix_power(a, 0.5)
    >>> b
    array([[ 0.75592895,  1.13389342],
           [ 0.37796447,  1.88982237]])
    >>> np.dot(b, b)      # Verify square root
    array([[ 1.,  3.],
           [ 1.,  4.]])

    r   N)r;   scipy.linalg._matfuncs_inv_ssqlinalg_matfuncs_inv_ssq_fractional_matrix_power)r9   tscipys      r:   r)   r)   b   s/    R 	A)<<))BB1aHHr<   c                    t        j                  |       } ddl}|j                  j                  j                  |       }t        | |      }dt        z  }t        j                  dd      5  t        t        |      | z
  d      t        j                  t        | d      | j                        j                  d   z  }ddd       |r3t              r||k\  r!d	| }t        j                  |t         d
       |S |fS # 1 sw Y   BxY w)a  
    Compute matrix logarithm.

    The matrix logarithm is the inverse of
    expm: expm(logm(`A`)) == `A`

    Parameters
    ----------
    A : (N, N) array_like
        Matrix whose logarithm to evaluate
    disp : bool, optional
        Emit warning if error in the result is estimated large
        instead of returning estimated error. (Default: True)

    Returns
    -------
    logm : (N, N) ndarray
        Matrix logarithm of `A`
    errest : float
        (if disp == False)

        1-norm of the estimated error, ||err||_1 / ||A||_1

    References
    ----------
    .. [1] Awad H. Al-Mohy and Nicholas J. Higham (2012)
           "Improved Inverse Scaling and Squaring Algorithms
           for the Matrix Logarithm."
           SIAM Journal on Scientific Computing, 34 (4). C152-C169.
           ISSN 1095-7197

    .. [2] Nicholas J. Higham (2008)
           "Functions of Matrices: Theory and Computation"
           ISBN 978-0-898716-46-7

    .. [3] Nicholas J. Higham and Lijing lin (2011)
           "A Schur-Pade Algorithm for Fractional Powers of a Matrix."
           SIAM Journal on Matrix Analysis and Applications,
           32 (3). pp. 1056-1078. ISSN 0895-4798

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import logm, expm
    >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
    >>> b = logm(a)
    >>> b
    array([[-1.02571087,  2.05142174],
           [ 0.68380725,  1.02571087]])
    >>> expm(b)         # Verify expm(logm(a)) returns a
    array([[ 1.,  3.],
           [ 1.,  4.]])

    r   N  ignore)divideinvalidr   rG    z1logm result may be inaccurate, approximate err = r2   )
stacklevel)r3   r4   rP   rQ   rR   _logmrN   rE   errstater   r   rG   rK   r   warningswarnRuntimeWarning)r9   disprU   r/   errtolerrestmessages          r:   r&   r&      s    n 	

1A)&&,,Q/AAqA#XF	Hh	7 Ud1gai#bjja177&K&P&PQS&TTU6V#3I&RGMM'>a@&yU Us   +AC>>Dc           
      d	   t        j                  |       }|j                  dk(  rG|j                  dk  r8t        j                  t        j
                  |j                               gg      S |j                  dk  rt        d      |j                  d   |j                  d   k7  rt        d      t        |j                   dk(  rKt        t        j                  d|j                              j                  }t        j                  ||      S |j                  dd	 d
k(  rt        j
                  |      S t        j                  |j                  t         j                        s |j!                  t         j"                        }n<|j                  t         j$                  k(  r|j!                  t         j&                        }|j                  d   }t        j(                  |j                  |j                        }t        j(                  d||f|j                        }t+        |j                  d	d D cg c]  }t-        |       c} D ]\  }||   }t/        |      }	t1        |	      s?t        j2                  t        j
                  t        j2                  |                  ||<   ^||dd	d	d	d	f<   t5        |      \  }
}|
dk  rt7        d|
 d      t9        ||
      }|dk7  r#|dk  rt7        d| d      t;        d| d      |d   }|dk7  rF|	d   dk(  s	|	d   dk(  r t        j2                  |      }t        j
                  |d| z  z        t        j<                  d|      d	d	 t        j2                  ||	d   dk(  rdnd      }t-        |dz
  dd      D ]  }||z  }t        j
                  |d| z  z        t        j<                  d|      d	d	 t?        |d| z  z        |d| z  z  z  }|	d   dk(  r#|t        j<                  d|dd	d	df         d	d	 |t        j<                  d|d	ddd	f         d	d	  nt-        |      D ]  }||z  }	 |	d   dk(  s|	d   dk(  r7|	d   dk(  rt        j@                  |      nt        jB                  |      ||<   X|||<   _ |S c c}w )a  Compute the matrix exponential of an array.

    Parameters
    ----------
    A : ndarray
        Input with last two dimensions are square ``(..., n, n)``.

    Returns
    -------
    eA : ndarray
        The resulting matrix exponential with the same shape of ``A``

    Notes
    -----
    Implements the algorithm given in [1], which is essentially a Pade
    approximation with a variable order that is decided based on the array
    data.

    For input with size ``n``, the memory usage is in the worst case in the
    order of ``8*(n**2)``. If the input data is not of single and double
    precision of real and complex dtypes, it is copied to a new array.

    For cases ``n >= 400``, the exact 1-norm computation cost, breaks even with
    1-norm estimation and from that point on the estimation scheme given in
    [2] is used to decide on the approximation order.

    References
    ----------
    .. [1] Awad H. Al-Mohy and Nicholas J. Higham, (2009), "A New Scaling
           and Squaring Algorithm for the Matrix Exponential", SIAM J. Matrix
           Anal. Appl. 31(3):970-989, :doi:`10.1137/09074721X`

    .. [2] Nicholas J. Higham and Francoise Tisseur (2000), "A Block Algorithm
           for Matrix 1-Norm Estimation, with an Application to 1-Norm
           Pseudospectra." SIAM J. Matrix Anal. Appl. 21(4):1185-1201,
           :doi:`10.1137/S0895479899356080`

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import expm, sinm, cosm

    Matrix version of the formula exp(0) = 1:

    >>> expm(np.zeros((3, 2, 2)))
    array([[[1., 0.],
            [0., 1.]],
    <BLANKLINE>
           [[1., 0.],
            [0., 1.]],
    <BLANKLINE>
           [[1., 0.],
            [0., 1.]]])

    Euler's identity (exp(i*theta) = cos(theta) + i*sin(theta))
    applied to a matrix:

    >>> a = np.array([[1.0, 2.0], [-1.0, 3.0]])
    >>> expm(1j*a)
    array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
           [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])
    >>> cosm(a) + 1j*sinm(a)
    array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
           [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])

    r   r2   z0The input array must be at least two-dimensionalz-Last 2 dimensions of the array must be squarer   r[   N)r   r      znscipy.linalg.expm could not allocate sufficient memory while trying to compute the Pade structure (error code z).izkscipy.linalg.expm could not allocate sufficient memory while trying to compute the exponential (error code z^scipy.linalg.expm got an internal LAPACK error during the exponential computation (error code )zii->i)kg       @)"r3   r4   sizendimarrayexpitemr   r6   minr   eyerG   
empty_like
issubdtypeinexactastypefloat64float16float32emptyr   ranger   anyr   r   MemoryErrorr   RuntimeErroreinsum
_exp_sinchr   tril)r9   arG   neAAmxindawlumsinfoeAwdiag_awsdr-   exp_sd_s                      r:   r   r      s8   F 	

1Avv{qvvzxx"&&*+,--vvzLMMwwr{aggbk!IJJ AGG}RVVAQWW-.44}}Qe,, 	wwrs|vvvay=="**-HHRZZ 	
BJJ	HHRZZ  	
A	!''	)B	1a)177	+B 1773B<8aq89 >sVr]2wggbffRWWR[12BsG
 1a7"2&1E 778c= > > B"19s{! #99=b#B C C # $226q$: ; ; e61
1
 ''"+-/VVGa1"g4E-F		'3'*WWRA!2;qsB+ 	EA)C 24"r(8J1KBIIgs+A.'28(<=a1"gNF!uz>D		'3qr3B3w<8;>D		'3ssABw<8;	E q $A)C$ qEQJBqEQJ&(eqjbggclbggclBsGBsG}>@ IA 9s   5R-c                     t        j                  t        j                  |             }t        j                  |       }|dk(  }|| xx   ||    z  cc<   t        j                  | d d |         ||<   |S )Nr@   rh   )r3   diffrp   )r   	lexp_diffl_diffmask_zs       r:   r   r     si    q	"IWWQZFr\Fvg&&/)q"vf~.Ifr<   c                     t        |       } t        j                  |       r dt        d| z        t        d| z        z   z  S t        d| z        j                  S )a!  
    Compute the matrix cosine.

    This routine uses expm to compute the matrix exponentials.

    Parameters
    ----------
    A : (N, N) array_like
        Input array

    Returns
    -------
    cosm : (N, N) ndarray
        Matrix cosine of A

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import expm, sinm, cosm

    Euler's identity (exp(i*theta) = cos(theta) + i*sin(theta))
    applied to a matrix:

    >>> a = np.array([[1.0, 2.0], [-1.0, 3.0]])
    >>> expm(1j*a)
    array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
           [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])
    >>> cosm(a) + 1j*sinm(a)
    array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
           [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])

          ?              ?             )r;   r3   rC   r   rK   r8   s    r:   r    r      sM    B 	A	qDAJc!e,--BqDzr<   c                     t        |       } t        j                  |       r dt        d| z        t        d| z        z
  z  S t        d| z        j                  S )a   
    Compute the matrix sine.

    This routine uses expm to compute the matrix exponentials.

    Parameters
    ----------
    A : (N, N) array_like
        Input array.

    Returns
    -------
    sinm : (N, N) ndarray
        Matrix sine of `A`

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import expm, sinm, cosm

    Euler's identity (exp(i*theta) = cos(theta) + i*sin(theta))
    applied to a matrix:

    >>> a = np.array([[1.0, 2.0], [-1.0, 3.0]])
    >>> expm(1j*a)
    array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
           [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])
    >>> cosm(a) + 1j*sinm(a)
    array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
           [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])

    y             r   r   )r;   r3   rC   r   rJ   r8   s    r:   r!   r!     sM    B 	A	qd2a4j4A;.//BqDzr<   c           	      h    t        |       } t        | t        t        |       t	        |                   S )a  
    Compute the matrix tangent.

    This routine uses expm to compute the matrix exponentials.

    Parameters
    ----------
    A : (N, N) array_like
        Input array.

    Returns
    -------
    tanm : (N, N) ndarray
        Matrix tangent of `A`

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import tanm, sinm, cosm
    >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
    >>> t = tanm(a)
    >>> t
    array([[ -2.00876993,  -8.41880636],
           [ -2.80626879, -10.42757629]])

    Verify tanm(a) = sinm(a).dot(inv(cosm(a)))

    >>> s = sinm(a)
    >>> c = cosm(a)
    >>> s.dot(np.linalg.inv(c))
    array([[ -2.00876993,  -8.41880636],
           [ -2.80626879, -10.42757629]])

    )r;   rN   r   r    r!   r8   s    r:   r"   r"     s+    F 	Aq%Qa122r<   c                 b    t        |       } t        | dt        |       t        |        z   z        S )a  
    Compute the hyperbolic matrix cosine.

    This routine uses expm to compute the matrix exponentials.

    Parameters
    ----------
    A : (N, N) array_like
        Input array.

    Returns
    -------
    coshm : (N, N) ndarray
        Hyperbolic matrix cosine of `A`

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import tanhm, sinhm, coshm
    >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
    >>> c = coshm(a)
    >>> c
    array([[ 11.24592233,  38.76236492],
           [ 12.92078831,  50.00828725]])

    Verify tanhm(a) = sinhm(a).dot(inv(coshm(a)))

    >>> t = tanhm(a)
    >>> s = sinhm(a)
    >>> t - s.dot(np.linalg.inv(c))
    array([[  2.72004641e-15,   4.55191440e-15],
           [  0.00000000e+00,  -5.55111512e-16]])

    r   r;   rN   r   r8   s    r:   r#   r#     0    F 	Aq#a48!3455r<   c                 b    t        |       } t        | dt        |       t        |        z
  z        S )a  
    Compute the hyperbolic matrix sine.

    This routine uses expm to compute the matrix exponentials.

    Parameters
    ----------
    A : (N, N) array_like
        Input array.

    Returns
    -------
    sinhm : (N, N) ndarray
        Hyperbolic matrix sine of `A`

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import tanhm, sinhm, coshm
    >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
    >>> s = sinhm(a)
    >>> s
    array([[ 10.57300653,  39.28826594],
           [ 13.09608865,  49.86127247]])

    Verify tanhm(a) = sinhm(a).dot(inv(coshm(a)))

    >>> t = tanhm(a)
    >>> c = coshm(a)
    >>> t - s.dot(np.linalg.inv(c))
    array([[  2.72004641e-15,   4.55191440e-15],
           [  0.00000000e+00,  -5.55111512e-16]])

    r   r   r8   s    r:   r$   r$   (  r   r<   c           	      h    t        |       } t        | t        t        |       t	        |                   S )a  
    Compute the hyperbolic matrix tangent.

    This routine uses expm to compute the matrix exponentials.

    Parameters
    ----------
    A : (N, N) array_like
        Input array

    Returns
    -------
    tanhm : (N, N) ndarray
        Hyperbolic matrix tangent of `A`

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import tanhm, sinhm, coshm
    >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
    >>> t = tanhm(a)
    >>> t
    array([[ 0.3428582 ,  0.51987926],
           [ 0.17329309,  0.86273746]])

    Verify tanhm(a) = sinhm(a).dot(inv(coshm(a)))

    >>> s = sinhm(a)
    >>> c = coshm(a)
    >>> t - s.dot(np.linalg.inv(c))
    array([[  2.72004641e-15,   4.55191440e-15],
           [  0.00000000e+00,  -5.55111512e-16]])

    )r;   rN   r   r#   r$   r8   s    r:   r%   r%   O  s+    F 	Aq%a%(344r<   c                     t        |       } t        |       \  }}t        ||      \  }}|j                  \  }}t	         |t	        |                  }|j                  |j                  j                        }t        |d         }t        ||||      \  }}t        t        ||      t        t        |                  }t        | |      }t        t        dt         |j                  j                        }|dk(  r|}t#        dt%        |||z  t'        t)        |d      d      z              }	t+        t-        t/        t1        |                  d      rt2        j4                  }	|r|	d|z  kD  rt7        d|	       |S ||	fS )	a  
    Evaluate a matrix function specified by a callable.

    Returns the value of matrix-valued function ``f`` at `A`. The
    function ``f`` is an extension of the scalar-valued function `func`
    to matrices.

    Parameters
    ----------
    A : (N, N) array_like
        Matrix at which to evaluate the function
    func : callable
        Callable object that evaluates a scalar function f.
        Must be vectorized (eg. using vectorize).
    disp : bool, optional
        Print warning if error in the result is estimated large
        instead of returning estimated error. (Default: True)

    Returns
    -------
    funm : (N, N) ndarray
        Value of the matrix function specified by func evaluated at `A`
    errest : float
        (if disp == False)

        1-norm of the estimated error, ||err||_1 / ||A||_1

    Notes
    -----
    This function implements the general algorithm based on Schur decomposition
    (Algorithm 9.1.1. in [1]_).

    If the input matrix is known to be diagonalizable, then relying on the
    eigendecomposition is likely to be faster. For example, if your matrix is
    Hermitian, you can do

    >>> from scipy.linalg import eigh
    >>> def funm_herm(a, func, check_finite=False):
    ...     w, v = eigh(a, check_finite=check_finite)
    ...     ## if you further know that your matrix is positive semidefinite,
    ...     ## you can optionally guard against precision errors by doing
    ...     # w = np.maximum(w, 0)
    ...     w = func(w)
    ...     return (v * w).dot(v.conj().T)

    References
    ----------
    .. [1] Gene H. Golub, Charles F. van Loan, Matrix Computations 4th ed.

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import funm
    >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
    >>> funm(a, lambda x: x*x)
    array([[  4.,  15.],
           [  5.,  19.]])
    >>> a.dot(a)
    array([[  4.,  15.],
           [  5.,  19.]])

    )r   r   r?   r@   r   r   )axisrW   z0funm result may be inaccurate, approximate err =)r;   r   r   r6   r   rw   rG   rH   absr   r   r	   r
   rN   rD   rE   rF   rr   maxr   r   r   r   r   r   r3   infprint)
r9   funcrc   TZr   r/   mindenrM   errs
             r:   r'   r'   v  sD   ~ 	A8DAq1a=DAq77DAqT$q']A	A4\F Aq!V,IAvC1Iy1./AAqAs
,QWW\\:
;C}
aS3v:tDAJ'::;
<CE+hqk*+!4ffc>DcJ#vr<   c                 R   t        |       } d }t        | |d      \  }}dt        z  dt        z  dt        |j
                  j                        }||k  r|S t        | d      }t        j                  |      }d|z  }| |t        j                  | j                  d         z  z   }	|}
t        d	      D ]N  }t        |	      }d|	|z   z  }	dt        |	|	      |	z   z  }t        t        ||      |z
  d
      }||k  s|
|k(  r n|}
P |rt!        |      r||k\  rt#        d|       |	S |	|fS )a'  
    Matrix sign function.

    Extension of the scalar sign(x) to matrices.

    Parameters
    ----------
    A : (N, N) array_like
        Matrix at which to evaluate the sign function
    disp : bool, optional
        Print warning if error in the result is estimated large
        instead of returning estimated error. (Default: True)

    Returns
    -------
    signm : (N, N) ndarray
        Value of the sign function at `A`
    errest : float
        (if disp == False)

        1-norm of the estimated error, ||err||_1 / ||A||_1

    Examples
    --------
    >>> from scipy.linalg import signm, eigvals
    >>> a = [[1,2,3], [1,2,1], [1,1,1]]
    >>> eigvals(a)
    array([ 4.12488542+0.j, -0.76155718+0.j,  0.63667176+0.j])
    >>> eigvals(signm(a))
    array([-1.+0.j,  1.+0.j,  1.+0.j])

    c                     t        j                  |       }|j                  j                  dk(  rdt        z  t        |       z  }ndt        z  t        |       z  }t        t        |      |kD  |z        S )Nr,   r>   )	r3   rK   rG   rH   rD   r   rE   r   r   )r   rxcs      r:   rounded_signzsignm.<locals>.rounded_sign  s[    WWQZ88==CDa ACQAXb\A%+,,r<   r   )rc   r>   r?   F)
compute_uvr   d   r   z1signm result may be inaccurate, approximate err =)r;   r'   rD   rE   rF   rG   rH   r   r3   r   identityr6   r|   r   r   r   r   r   )r9   rc   r   resultre   rd   valsmax_svr   S0prev_errestr-   iS0Pps                 r:   r(   r(     s=   B 	A- !\2NFFTc#g&'78I8I'JKF qU#DWWT]F 	F
A	
Qr{{1771:&&	&BK3Z "g"s(^#b"+b.!c"bk"na(F?kV3 6V#3EvN	6zr<   c                 v   t        j                  |       } t        j                  |      }| j                  dk(  r|j                  dk(  st        d      | j                  d   |j                  d   k(  st        d      | j
                  dk(  s|j
                  dk(  rG| j                  d   |j                  d   z  }| j                  d   }t        j                  | ||f      S | dddt         j                  ddf   |dt         j                  ddddf   z  }|j                  d	|j                  dd z         S )
a  
    Khatri-rao product

    A column-wise Kronecker product of two matrices

    Parameters
    ----------
    a : (n, k) array_like
        Input array
    b : (m, k) array_like
        Input array

    Returns
    -------
    c:  (n*m, k) ndarray
        Khatri-rao product of `a` and `b`.

    Notes
    -----
    The mathematical definition of the Khatri-Rao product is:

    .. math::

        (A_{ij}  \bigotimes B_{ij})_{ij}

    which is the Kronecker product of every column of A and B, e.g.::

        c = np.vstack([np.kron(a[:, k], b[:, k]) for k in range(b.shape[1])]).T

    Examples
    --------
    >>> import numpy as np
    >>> from scipy import linalg
    >>> a = np.array([[1, 2, 3], [4, 5, 6]])
    >>> b = np.array([[3, 4, 5], [6, 7, 8], [2, 3, 9]])
    >>> linalg.khatri_rao(a, b)
    array([[ 3,  8, 15],
           [ 6, 14, 24],
           [ 2,  6, 27],
           [12, 20, 30],
           [24, 35, 48],
           [ 8, 15, 54]])

    r2   z(The both arrays should be 2-dimensional.r   z6The number of columns for both arrays should be equal.r   )r6   .N)rh   )	r3   r4   rn   r7   r6   rm   rt   newaxisreshape)r   br   r   r   s        r:   r*   r*   $  s   Z 	

1A


1AFFaKAFFaKCDD771:# , - 	- 	vv{affkGGAJ#GGAJ}}Qq!f-- 	
#q"**a
 1S"**a%:#;;A99UQWWQR[())r<   )N)T)<r`   	itertoolsr   numpyr3   r   r   r   r   r   r	   r
   r   r   r   r   r   scipy.linalgr   r   _miscr   _basicr   r   _decomp_svdr   _decomp_schurr   r   _expm_frechetr   r   _matfuncs_sqrtmr   _matfuncs_expmr   r   _linalg_pythranr   __all__finforE   rD   rF   r;   rN   r)   r&   r   r   r    r!   r"   r#   r$   r%   r'   r(   r*   r\   r<   r:   <module>r      s      D D D D 0    ) 2 " = (& bhhsmrxx}C 0L+I\FRdN%P%P$3N$6N$6N$5N[|M`?*r<   