o
    Ö­jYb  ã                   @   sŠ  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 )d¡j*Z*e )d¡j*Z+ddd dd ddœZ,dd„ Z-d1dd„Z.dd„ Z/d2dd„Z0dd„ Z1dd„ Z2dd „ Z3d!d"„ Z4d#d$„ Z5d%d&„ Z6d'd(„ Z7d)d*„ Z8d2d+d,„Z9d2d-d.„Z:d/d0„ Z;dS )3é    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                 C   s8   t  | ¡} t| jƒdks| jd | jd k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©ÚA© r8   úS/var/www/html/CropPilot/venv/lib/python3.10/site-packages/scipy/linalg/_matfuncs.pyÚ_asarray_square$   s   
"r:   c                 C   sV   t  | ¡r)t  |¡r)|du rtd td dœt|jj  }t j|j	d|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.

    Nç     @�@g    €„.A©r   r   ç        )Úatol)r1   Ú	isrealobjÚiscomplexobjÚfepsÚepsÚ_array_precisionÚdtypeÚcharÚallcloseÚimagÚreal)r7   ÚBÚtolr8   r8   r9   Ú_maybe_real<   s   rK   c                 C   s    t | ƒ} ddl}|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)r7   ÚtÚscipyr8   r8   r9   r(   b   s   )r(   Tc                 C   sÈ   t  | ¡} ddl}|jj | ¡}t| |ƒ}dt }t jddd�� t	t
|ƒ|  dƒt jt	| dƒ| jd�jd  }W d  ƒ n1 sBw   Y  |r`t|ƒrQ||kr^d	|› �}tj|td
d� |S ||fS )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   ©rD   r8   z1logm result may be inaccurate, approximate err = r0   )Ú
stacklevel)r1   r2   rL   rM   rN   Ú_logmrK   rB   Úerrstater   r   rD   rH   r   ÚwarningsÚwarnÚRuntimeWarning)r7   ÚdisprQ   r.   ÚerrtolÚerrestÚmessager8   r8   r9   r%   �   s   
7
0ÿ
r%   c              
   C   sŠ  t  | ¡}|jdkr|jdk rt  t  | ¡ ¡gg¡S |jdk r$tdƒ‚|jd |jd kr2tdƒ‚t	|jŽ dkrKt
t jd|jd�ƒj}t j||d�S |jdd	… d
krYt  |¡S t  |jt j¡sh| t j¡}n|jt jkrt| t j¡}|jd }t j|j|jd�}t jd||f|jd�}tdd„ |jd	d… D ƒŽ D �]&}|| }t|ƒ}t|ƒs¸t  t  t  |¡¡¡||< q›||dd	d	…d	d	…f< t|ƒ\}	}
|	dk rÕtd|	› d�ƒ‚t||	ƒ}|dkrò|dkrêtd|› d�ƒ‚td|› d�ƒ‚|d }|
dk�rœ|d dk�s	|d dk�r�t  |¡}t  |d|
   ¡t  d|¡d	d	…< t j||d dk�r,dndd�}t|
d ddƒD ]V}|| }t  |d|   ¡t  d|¡d	d	…< t|d|   ƒ|d|    }|d dk�r{|t  d|dd	…d	d…f ¡d	d	…< �q8|t  d|d	d…dd	…f ¡d	d	…< �q8nt|
ƒD ]}|| }�q”|d dk�sª|d dk�r¾|d dk�r¶t   |¡nt  !|¡||< q›|||< q›|S )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   r0   z0The input array must be at least two-dimensionaléÿÿÿÿéþÿÿÿz-Last 2 dimensions of the array must be squarer   rV   N)r   r   é   c                 S   s   g | ]}t |ƒ‘qS r8   )Úrange)Ú.0Úxr8   r8   r9   Ú
<listcomp>=  s    zexpm.<locals>.<listcomp>znscipy.linalg.expm could not allocate sufficient memory while trying to compute the Pade structure (error code z).iõÿÿÿzkscipy.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       @)"r1   r2   ÚsizeÚndimÚarrayÚexpÚitemr   r4   Úminr   ÚeyerD   Ú
empty_likeÚ
issubdtypeÚinexactÚastypeÚfloat64Úfloat16Úfloat32Úemptyr   r   Úanyr   r   ÚMemoryErrorr   ÚRuntimeErrorÚeinsumrd   Ú
_exp_sinchr   Útril)r7   ÚarD   ÚnÚeAÚAmÚindÚawÚluÚmÚsÚinfoÚeAwÚdiag_awÚsdr,   Úexp_sdÚ_r8   r8   r9   r   Ù   sx   
C


"
þ

þ
þ

$ $ ((÷(
r   c                 C   sX   t  t  | ¡¡}t  | ¡}|dk}||   ||    < t  | d d… | ¡||< |S )Nr=   ra   )r1   Údiffrm   )rf   Ú	lexp_diffÚl_diffÚmask_zr8   r8   r9   r}   €  s   
r}   c                 C   s<   t | ƒ} t | ¡rdtd|  ƒtd|  ƒ  S td|  ƒ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:   r1   r@   r   rH   r6   r8   r8   r9   r   Š  ó   !
r   c                 C   s<   t | ƒ} t | ¡rdtd|  ƒtd|  ƒ  S td|  ƒ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:   r1   r@   r   rG   r6   r8   r8   r9   r    ²  r•   r    c                 C   ó    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:   rK   r   r   r    r6   r8   r8   r9   r!   Ú  ó   #r!   c                 C   s$   t | ƒ} t| dt| ƒt|  ƒ  ƒ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:   rK   r   r6   r8   r8   r9   r"     ó   #r"   c                 C   s$   t | ƒ} t| dt| ƒt|  ƒ  ƒ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˜   r6   r8   r8   r9   r#   (  r™   r#   c                 C   r–   )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:   rK   r   r"   r#   r6   r8   r8   r9   r$   O  r—   r$   c           
   	   C   s  t | ƒ} t| ƒ\}}t||ƒ\}}|j\}}t|t|ƒƒƒ}| |jj¡}t|d ƒ}t	||||ƒ\}}t
t
||ƒtt|ƒƒƒ}t| |ƒ}ttdœt|jj  }|dkrV|}tdt||| tt|dƒdƒ ƒƒ}	tttt|ƒƒƒdd�rwtj}	|r†|	d| kr„t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   )ÚaxisrR   z0funm result may be inaccurate, approximate err =)r:   r   r   r4   r   rt   rD   rE   Úabsr   r   r   r	   rK   rA   rB   rC   ro   Úmaxr   r   r   r   r   r   r1   ÚinfÚprint)
r7   Úfuncr]   ÚTÚZr€   r.   ÚmindenrJ   Úerrr8   r8   r9   r&   v  s*   ?

$
r&   c                 C   s  t | ƒ} dd„ }t| |dd�\}}dt dt dœt|jj  }||k r&|S t| dd�}t 	|¡}d	| }| |t 
| jd ¡  }	|}
td
ƒD ]+}t|	ƒ}d	|	|  }	d	t|	|	ƒ|	  }tt||ƒ| dƒ}||k sn|
|krp n|}
qG|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                 S   sL   t  | ¡}|jjdkrdt t| ƒ }ndt t| ƒ }tt|ƒ|k| ƒS )Nr+   r;   )	r1   rH   rD   rE   rA   r   rB   r   r
   )rf   ÚrxÚcr8   r8   r9   Úrounded_sign÷  s
   
zsignm.<locals>.rounded_signr   )r]   r;   r<   F)Ú
compute_uvr’   éd   r   z1signm result may be inaccurate, approximate err =)r:   r&   rA   rB   rC   rD   rE   r   r1   r   Úidentityr4   rd   r   r   r   r   rž   )r7   r]   r¦   Úresultr_   r^   ÚvalsÚmax_svr¥   ÚS0Úprev_errestr,   ÚiS0ÚPpr8   r8   r9   r'   Ô  s0   !

r'   c                 C   sÜ   t  | ¡} t  |¡}| jdkr|jdkstdƒ‚| jd |jd ks&tdƒ‚| jdks0|jdkrH| jd |jd  }| jd }t j| ||fd�S | ddd…t jdd…f |dt jdd…dd…f  }| d	|jdd…  ¡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]])

    r0   z(The both arrays should be 2-dimensional.r   z6The number of columns for both arrays should be equal.r   )r4   .N)ra   )	r1   r2   rk   r5   r4   rj   rq   ÚnewaxisÚreshape)r   Úbr†   r€   r¥   r8   r8   r9   r)   $  s   
-

4r)   )N)T)<rZ   Ú	itertoolsr   Únumpyr1   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__ÚfinforB   rA   rC   r:   rK   r(   r%   r   r}   r   r    r!   r"   r#   r$   r&   r'   r)   r8   r8   r8   r9   Ú<module>   sB   8
&
.I (
(('''
'
^P