o
    Ö­jìr  ã                   @   s  d Z ddlZddlZddlmZ ddlmZmZm	Z	m
Z
 ddgZG dd„ dƒZG dd	„ d	eƒZG d
d„ deƒZG dd„ deƒZddd„ZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdd„ ZdS ) aU  Abstract linear algebra library.

This module defines a class hierarchy that implements a kind of "lazy"
matrix representation, called the ``LinearOperator``. It can be used to do
linear algebra with extremely large sparse or structured matrices, without
representing those explicitly in memory. Such matrices can be added,
multiplied, transposed, etc.

As a motivating example, suppose you want have a matrix where almost all of
the elements have the value one. The standard sparse matrix representation
skips the storage of zeros, but not ones. By contrast, a LinearOperator is
able to represent such matrices efficiently. First, we need a compact way to
represent an all-ones matrix::

    >>> import numpy as np
    >>> from scipy.sparse.linalg._interface import LinearOperator
    >>> class Ones(LinearOperator):
    ...     def __init__(self, shape):
    ...         super().__init__(dtype=None, shape=shape)
    ...     def _matvec(self, x):
    ...         return np.repeat(x.sum(), self.shape[0])

Instances of this class emulate ``np.ones(shape)``, but using a constant
amount of storage, independent of ``shape``. The ``_matvec`` method specifies
how this linear operator multiplies with (operates on) a vector. We can now
add this operator to a sparse matrix that stores only offsets from one::

    >>> from scipy.sparse.linalg._interface import aslinearoperator
    >>> from scipy.sparse import csr_array
    >>> offsets = csr_array([[1, 0, 2], [0, -1, 0], [0, 0, 3]])
    >>> A = aslinearoperator(offsets) + Ones(offsets.shape)
    >>> A.dot([1, 2, 3])
    array([13,  4, 15])

The result is the same as that given by its dense, explicitly-stored
counterpart::

    >>> (np.ones(A.shape, A.dtype) + offsets.toarray()).dot([1, 2, 3])
    array([13,  4, 15])

Several algorithms in the ``scipy.sparse`` library are able to operate on
``LinearOperator`` instances.
é    N)Úissparse)ÚisshapeÚ	isintlikeÚasmatrixÚis_pydata_spmatrixÚLinearOperatorÚaslinearoperatorc                       s  e Zd ZdZdZdZ‡ fdd„Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ ZeeƒZ d6d7„ Z!ee!ƒZ"d8d9„ Z#d:d;„ Z$‡  Z%S )<r   al  Common interface for performing matrix vector products

    Many iterative methods (e.g. cg, gmres) do not need to know the
    individual entries of a matrix to solve a linear system A@x=b.
    Such solvers only require the computation of matrix vector
    products, A@v where v is a dense vector.  This class serves as
    an abstract interface between iterative solvers and matrix-like
    objects.

    To construct a concrete LinearOperator, either pass appropriate
    callables to the constructor of this class, or subclass it.

    A subclass must implement either one of the methods ``_matvec``
    and ``_matmat``, and the attributes/properties ``shape`` (pair of
    integers) and ``dtype`` (may be None). It may call the ``__init__``
    on this class to have these attributes validated. Implementing
    ``_matvec`` automatically implements ``_matmat`` (using a naive
    algorithm) and vice-versa.

    Optionally, a subclass may implement ``_rmatvec`` or ``_adjoint``
    to implement the Hermitian adjoint (conjugate transpose). As with
    ``_matvec`` and ``_matmat``, implementing either ``_rmatvec`` or
    ``_adjoint`` implements the other automatically. Implementing
    ``_adjoint`` is preferable; ``_rmatvec`` is mostly there for
    backwards compatibility.

    Parameters
    ----------
    shape : tuple
        Matrix dimensions (M, N).
    matvec : callable f(v)
        Returns returns A @ v.
    rmatvec : callable f(v)
        Returns A^H @ v, where A^H is the conjugate transpose of A.
    matmat : callable f(V)
        Returns A @ V, where V is a dense matrix with dimensions (N, K).
    dtype : dtype
        Data type of the matrix.
    rmatmat : callable f(V)
        Returns A^H @ V, where V is a dense matrix with dimensions (M, K).

    Attributes
    ----------
    args : tuple
        For linear operators describing products etc. of other linear
        operators, the operands of the binary operation.
    ndim : int
        Number of dimensions (this is always 2)

    See Also
    --------
    aslinearoperator : Construct LinearOperators

    Notes
    -----
    The user-defined matvec() function must properly handle the case
    where v has shape (N,) as well as the (N,1) case.  The shape of
    the return type is handled internally by LinearOperator.

    It is highly recommended to explicitly specify the `dtype`, otherwise
    it is determined automatically at the cost of a single matvec application
    on `int8` zero vector using the promoted `dtype` of the output.
    Python `int` could be difficult to automatically cast to numpy integers
    in the definition of the `matvec` so the determination may be inaccurate.
    It is assumed that `matmat`, `rmatvec`, and `rmatmat` would result in
    the same dtype of the output given an `int8` input as `matvec`.

    LinearOperator instances can also be multiplied, added with each
    other and exponentiated, all lazily: the result of these operations
    is always a new, composite LinearOperator, that defers linear
    operations to the original operators and combines the results.

    More details regarding how to subclass a LinearOperator and several
    examples of concrete LinearOperator instances can be found in the
    external project `PyLops <https://pylops.readthedocs.io>`_.


    Examples
    --------
    >>> import numpy as np
    >>> from scipy.sparse.linalg import LinearOperator
    >>> def mv(v):
    ...     return np.array([2*v[0], 3*v[1]])
    ...
    >>> A = LinearOperator((2,2), matvec=mv)
    >>> A
    <2x2 _CustomLinearOperator with dtype=int8>
    >>> A.matvec(np.ones(2))
    array([ 2.,  3.])
    >>> A @ np.ones(2)
    array([ 2.,  3.])

    é   Nc                    sT   | t u r
tƒ  t¡S tƒ  | ¡}t|ƒjt jkr(t|ƒjt jkr(tjdt	dd� |S )NzMLinearOperator subclass should implement at least one of _matvec and _matmat.r	   )ÚcategoryÚ
stacklevel)
r   ÚsuperÚ__new__Ú_CustomLinearOperatorÚtypeÚ_matvecÚ_matmatÚwarningsÚwarnÚRuntimeWarning)ÚclsÚargsÚkwargsÚobj©Ú	__class__© ú[/var/www/html/CropPilot/venv/lib/python3.10/site-packages/scipy/sparse/linalg/_interface.pyr   š   s   þzLinearOperator.__new__c                 C   sB   |dur	t  |¡}t|ƒ}t|ƒstd|›d�ƒ‚|| _|| _dS )z¡Initialize this LinearOperator.

        To be called by subclasses. ``dtype`` may be None; ``shape`` should
        be convertible to a length-2 tuple.
        Nzinvalid shape z (must be 2-d))ÚnpÚdtypeÚtupler   Ú
ValueErrorÚshape)Úselfr   r!   r   r   r   Ú__init__©   s   

zLinearOperator.__init__c                 C   sf   | j du r1tj| jd tjd�}z
t |  |¡¡}W n ty*   t  t¡| _ Y dS w |j | _ dS dS )aø  Determine the dtype by executing `matvec` on an `int8` test vector.

        In `np.promote_types` hierarchy, the type `int8` is the smallest,
        so we call `matvec` on `int8` and use the promoted dtype of the output
        to set the default `dtype` of the `LinearOperator`.
        We assume that `matmat`, `rmatvec`, and `rmatmat` would result in
        the same dtype of the output given an `int8` input as `matvec`.

        Called from subclasses at the end of the __init__ routine.
        Néÿÿÿÿ)r   )	r   r   Úzerosr!   Úint8ÚasarrayÚmatvecÚOverflowErrorÚint)r"   ÚvÚmatvec_vr   r   r   Ú_init_dtype¹   s   
þøzLinearOperator._init_dtypec                    s   t  ‡ fdd„|jD ƒ¡S )zÌDefault matrix-matrix multiplication handler.

        Falls back on the user-defined _matvec method, so defining that will
        define matrix multiplication (though in a very suboptimal way).
        c                    ó   g | ]}ˆ   | d d¡¡‘qS ©r$   é   )r(   Úreshape©Ú.0Úcol©r"   r   r   Ú
<listcomp>Õ   ó    z*LinearOperator._matmat.<locals>.<listcomp>)r   ÚhstackÚT©r"   ÚXr   r5   r   r   Î   s   zLinearOperator._matmatc                 C   s   |   | dd¡¡S )ay  Default matrix-vector multiplication handler.

        If self is a linear operator of shape (M, N), then this method will
        be called on a shape (N,) or (N, 1) ndarray, and should return a
        shape (M,) or (M, 1) ndarray.

        This default implementation falls back on _matmat, so defining that
        will define matrix-vector multiplication as well.
        r$   r0   )Úmatmatr1   ©r"   Úxr   r   r   r   ×   s   
zLinearOperator._matvecc                 C   sš   t  |¡}| j\}}|j|fkr|j|dfkrtdƒ‚|  |¡}t|t jƒr+t|ƒ}nt  |¡}|j	dkr<| 
|¡}|S |j	dkrI| 
|d¡}|S tdƒ‚)ax  Matrix-vector multiplication.

        Performs the operation y=A@x where A is an MxN linear
        operator and x is a column vector or 1-d array.

        Parameters
        ----------
        x : {matrix, ndarray}
            An array with shape (N,) or (N,1).

        Returns
        -------
        y : {matrix, ndarray}
            A matrix or ndarray with shape (M,) or (M,1) depending
            on the type and shape of the x argument.

        Notes
        -----
        This matvec wraps the user-specified matvec routine or overridden
        _matvec method to ensure that y has the correct shape and type.

        r0   údimension mismatchr	   z/invalid shape returned by user-defined matvec())r   Ú
asanyarrayr!   r    r   Ú
isinstanceÚmatrixr   r'   Úndimr1   ©r"   r>   ÚMÚNÚyr   r   r   r(   ã   ó   







ûþzLinearOperator.matvecc                 C   sš   t  |¡}| j\}}|j|fkr|j|dfkrtdƒ‚|  |¡}t|t jƒr+t|ƒ}nt  |¡}|j	dkr<| 
|¡}|S |j	dkrI| 
|d¡}|S tdƒ‚)a‰  Adjoint matrix-vector multiplication.

        Performs the operation y = A^H @ x where A is an MxN linear
        operator and x is a column vector or 1-d array.

        Parameters
        ----------
        x : {matrix, ndarray}
            An array with shape (M,) or (M,1).

        Returns
        -------
        y : {matrix, ndarray}
            A matrix or ndarray with shape (N,) or (N,1) depending
            on the type and shape of the x argument.

        Notes
        -----
        This rmatvec wraps the user-specified rmatvec routine or overridden
        _rmatvec method to ensure that y has the correct shape and type.

        r0   r?   r	   z0invalid shape returned by user-defined rmatvec())r   r@   r!   r    Ú_rmatvecrA   rB   r   r'   rC   r1   rD   r   r   r   Úrmatvec  rH   zLinearOperator.rmatvecc                 C   sR   t | ƒjtjkr#t| dƒr!t | ƒjtjkr!|  | dd¡¡ d¡S t‚| j |¡S )z6Default implementation of _rmatvec; defers to adjoint.Ú_rmatmatr$   r0   )	r   Ú_adjointr   ÚhasattrrK   r1   ÚNotImplementedErrorÚHr(   r=   r   r   r   rI   A  s   
zLinearOperator._rmatvecc              
   C   s¾   t |ƒst|ƒst |¡}|jdkrtd|j› d�ƒ‚|jd | jd kr1td| j› d|j› �ƒ‚z|  |¡}W n tyR } zt |ƒsHt|ƒrMt	dƒ|‚‚ d	}~ww t
|tjƒr]t|ƒ}|S )
aP  Matrix-matrix multiplication.

        Performs the operation y=A@X where A is an MxN linear
        operator and X dense N*K matrix or ndarray.

        Parameters
        ----------
        X : {matrix, ndarray}
            An array with shape (N,K).

        Returns
        -------
        Y : {matrix, ndarray}
            A matrix or ndarray with shape (M,K) depending on
            the type of the X argument.

        Notes
        -----
        This matmat wraps any user-specified matmat routine or overridden
        _matmat method to ensure that y has the correct type.

        r	   z$expected 2-d ndarray or matrix, not z-dr   r0   údimension mismatch: ú, zdUnable to multiply a LinearOperator with a sparse matrix. Wrap the matrix in aslinearoperator first.N)r   r   r   r@   rC   r    r!   r   Ú	ExceptionÚ	TypeErrorrA   rB   r   ©r"   r;   ÚYÚer   r   r   r<   M  s*   

ÿý€úzLinearOperator.matmatc              
   C   sº   t |ƒst|ƒst |¡}|jdkrtd|j ƒ‚|jd | jd kr/td| j› d|j› �ƒ‚z|  |¡}W n tyP } zt |ƒsFt|ƒrKt	dƒ|‚‚ d}~ww t
|tjƒr[t|ƒ}|S )a;  Adjoint matrix-matrix multiplication.

        Performs the operation y = A^H @ x where A is an MxN linear
        operator and x is a column vector or 1-d array, or 2-d array.
        The default implementation defers to the adjoint.

        Parameters
        ----------
        X : {matrix, ndarray}
            A matrix or 2D array.

        Returns
        -------
        Y : {matrix, ndarray}
            A matrix or 2D array depending on the type of the input.

        Notes
        -----
        This rmatmat wraps the user-specified rmatmat routine.

        r	   z(expected 2-d ndarray or matrix, not %d-dr   rP   rQ   zfUnable to multiply a LinearOperator with a sparse matrix. Wrap the matrix in aslinearoperator() first.N)r   r   r   r@   rC   r    r!   rK   rR   rS   rA   rB   r   rT   r   r   r   Úrmatmat|  s.   

ÿÿý€úzLinearOperator.rmatmatc                    s6   t ˆ ƒjtjkrt ‡ fdd„|jD ƒ¡S ˆ j |¡S )z@Default implementation of _rmatmat defers to rmatvec or adjoint.c                    r.   r/   )rJ   r1   r2   r5   r   r   r6   ­  r7   z+LinearOperator._rmatmat.<locals>.<listcomp>)r   rL   r   r   r8   r9   rO   r<   r:   r   r5   r   rK   ª  s   zLinearOperator._rmatmatc                 C   s   | | S ©Nr   r=   r   r   r   Ú__call__±  s   zLinearOperator.__call__c                 C   ó
   |   |¡S rX   )Údotr=   r   r   r   Ú__mul__´  ó   
zLinearOperator.__mul__c                 C   s    t  |¡s	tdƒ‚t| d| ƒS )Nz.Can only divide a linear operator by a scalar.g      ð?)r   Úisscalarr    Ú_ScaledLinearOperator©r"   Úotherr   r   r   Ú__truediv__·  s   
zLinearOperator.__truediv__c                 C   s�   t |tƒr
t| |ƒS t |¡rt| |ƒS t|ƒs!t|ƒs!t |¡}|j	dks2|j	dkr7|j
d dkr7|  |¡S |j	dkrA|  |¡S td|›�ƒ‚)ar  Matrix-matrix or matrix-vector multiplication.

        Parameters
        ----------
        x : array_like
            1-d or 2-d array, representing a vector or matrix.

        Returns
        -------
        Ax : array
            1-d or 2-d array (depending on the shape of x) that represents
            the result of applying this linear operator on x.

        r0   r	   ú)expected 1-d or 2-d array or matrix, got )rA   r   Ú_ProductLinearOperatorr   r^   r_   r   r   r'   rC   r!   r(   r<   r    r=   r   r   r   r[   ½  s   




"


zLinearOperator.dotc                 C   ó   t  |¡r	tdƒ‚|  |¡S ©Nz0Scalar operands are not allowed, use '*' instead)r   r^   r    r\   r`   r   r   r   Ú
__matmul__Ü  ó   

zLinearOperator.__matmul__c                 C   re   rf   )r   r^   r    Ú__rmul__r`   r   r   r   Ú__rmatmul__â  rh   zLinearOperator.__rmatmul__c                 C   s   t  |¡r
t| |ƒS |  |¡S rX   )r   r^   r_   Ú_rdotr=   r   r   r   ri   è  s   


zLinearOperator.__rmul__c                 C   sœ   t |tƒr
t|| ƒS t |¡rt| |ƒS t|ƒs!t|ƒs!t |¡}|j	dks2|j	dkr:|j
d dkr:| j |j¡jS |j	dkrG| j |j¡jS td|›�ƒ‚)aï  Matrix-matrix or matrix-vector multiplication from the right.

        Parameters
        ----------
        x : array_like
            1-d or 2-d array, representing a vector or matrix.

        Returns
        -------
        xA : array
            1-d or 2-d array (depending on the shape of x) that represents
            the result of applying this linear operator on x from the right.

        Notes
        -----
        This is copied from dot to implement right multiplication.
        r0   r	   r   rc   )rA   r   rd   r   r^   r_   r   r   r'   rC   r!   r9   r(   r<   r    r=   r   r   r   rk   î  s   




"
zLinearOperator._rdotc                 C   s   t  |¡r
t| |ƒS tS rX   )r   r^   Ú_PowerLinearOperatorÚNotImplemented)r"   Úpr   r   r   Ú__pow__  ó   

zLinearOperator.__pow__c                 C   s   t |tƒr
t| |ƒS tS rX   )rA   r   Ú_SumLinearOperatorrm   r=   r   r   r   Ú__add__  rp   zLinearOperator.__add__c                 C   s
   t | dƒS )Nr$   )r_   r5   r   r   r   Ú__neg__  r]   zLinearOperator.__neg__c                 C   s   |   | ¡S rX   )rr   r=   r   r   r   Ú__sub__!  ó   zLinearOperator.__sub__c                 C   s<   | j \}}| jd u rd}ndt| jƒ }d||| jj|f S )Nzunspecified dtypezdtype=z<%dx%d %s with %s>)r!   r   Ústrr   Ú__name__)r"   rE   rF   Údtr   r   r   Ú__repr__$  s
   

zLinearOperator.__repr__c                 C   ó   |   ¡ S )aƒ  Hermitian adjoint.

        Returns the Hermitian adjoint of self, aka the Hermitian
        conjugate or Hermitian transpose. For a complex matrix, the
        Hermitian adjoint is equal to the conjugate transpose.

        Can be abbreviated self.H instead of self.adjoint().

        Returns
        -------
        A_H : LinearOperator
            Hermitian adjoint of self.
        )rL   r5   r   r   r   Úadjoint-  s   zLinearOperator.adjointc                 C   rz   )z´Transpose this linear operator.

        Returns a LinearOperator that represents the transpose of this one.
        Can be abbreviated self.T instead of self.transpose().
        )Ú
_transposer5   r   r   r   Ú	transpose?  s   zLinearOperator.transposec                 C   ó   t | ƒS )z6Default implementation of _adjoint; defers to rmatvec.)Ú_AdjointLinearOperatorr5   r   r   r   rL   I  ó   zLinearOperator._adjointc                 C   r~   )z? Default implementation of _transpose; defers to rmatvec + conj)Ú_TransposedLinearOperatorr5   r   r   r   r|   M  r€   zLinearOperator._transpose)&rw   Ú
__module__Ú__qualname__Ú__doc__rC   Ú__array_ufunc__r   r#   r-   r   r   r(   rJ   rI   r<   rW   rK   rY   r\   rb   r[   rg   rj   ri   rk   ro   rr   rs   rt   ry   r{   ÚpropertyrO   r}   r9   rL   r|   Ú__classcell__r   r   r   r   r   7   sD    ^	///.$	c                       sV   e Zd ZdZ		d‡ fdd„	Z‡ fdd„Zdd„ Zd	d
„ Z‡ fdd„Zdd„ Z	‡  Z
S )r   z>Linear operator defined in terms of user-specified operations.Nc                    s8   t ƒ  ||¡ d| _|| _|| _|| _|| _|  ¡  d S )Nr   )r   r#   r   Ú"_CustomLinearOperator__matvec_implÚ#_CustomLinearOperator__rmatvec_implÚ#_CustomLinearOperator__rmatmat_implÚ"_CustomLinearOperator__matmat_implr-   )r"   r!   r(   rJ   r<   r   rW   r   r   r   r#   U  s   z_CustomLinearOperator.__init__c                    ó    | j d ur
|   |¡S tƒ  |¡S rX   )r‹   r   r   r:   r   r   r   r   b  ó   

z_CustomLinearOperator._matmatc                 C   rZ   rX   )rˆ   r=   r   r   r   r   h  r]   z_CustomLinearOperator._matvecc                 C   s    | j }|d u rtdƒ‚|   |¡S )Nzrmatvec is not defined)r‰   rN   )r"   r>   Úfuncr   r   r   rI   k  s   
z_CustomLinearOperator._rmatvecc                    rŒ   rX   )rŠ   r   rK   r:   r   r   r   rK   q  r�   z_CustomLinearOperator._rmatmatc                 C   s.   t | jd | jd f| j| j| j| j| jd�S )Nr0   r   )r!   r(   rJ   r<   rW   r   )r   r!   r‰   rˆ   rŠ   r‹   r   r5   r   r   r   rL   w  s   ûz_CustomLinearOperator._adjoint)NNNN)rw   r‚   rƒ   r„   r#   r   r   rI   rK   rL   r‡   r   r   r   r   r   R  s    ÿr   c                       ó@   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Z‡  Z	S )r   z$Adjoint of arbitrary Linear Operatorc                    ó8   |j d |j d f}tƒ j|j|d� || _|f| _d S ©Nr0   r   )r   r!   ©r!   r   r#   r   ÚAr   ©r"   r“   r!   r   r   r   r#   ƒ  ó   z_AdjointLinearOperator.__init__c                 C   ó   | j  |¡S rX   )r“   rI   r=   r   r   r   r   ‰  ru   z_AdjointLinearOperator._matvecc                 C   r–   rX   )r“   r   r=   r   r   r   rI   Œ  ru   z_AdjointLinearOperator._rmatvecc                 C   r–   rX   )r“   rK   r=   r   r   r   r   �  ru   z_AdjointLinearOperator._matmatc                 C   r–   rX   )r“   r   r=   r   r   r   rK   ’  ru   z_AdjointLinearOperator._rmatmat©
rw   r‚   rƒ   r„   r#   r   rI   r   rK   r‡   r   r   r   r   r   €  s    r   c                       r�   )r�   z*Transposition of arbitrary Linear Operatorc                    r�   r‘   r’   r”   r   r   r   r#   ˜  r•   z"_TransposedLinearOperator.__init__c                 C   ó   t  | j t  |¡¡¡S rX   )r   Úconjr“   rI   r=   r   r   r   r   ž  ó   z!_TransposedLinearOperator._matvecc                 C   r˜   rX   )r   r™   r“   r   r=   r   r   r   rI   ¢  ó   z"_TransposedLinearOperator._rmatvecc                 C   r˜   rX   )r   r™   r“   rK   r=   r   r   r   r   ¥  rš   z!_TransposedLinearOperator._matmatc                 C   r˜   rX   )r   r™   r“   r   r=   r   r   r   rK   ©  r›   z"_TransposedLinearOperator._rmatmatr—   r   r   r   r   r�   •  s    r�   c                 C   s>   |d u rg }| D ]}|d urt |dƒr| |j¡ qtj|Ž S )Nr   )rM   Úappendr   r   Úresult_type)Ú	operatorsÚdtypesr   r   r   r   Ú
_get_dtype¬  s   €
r    c                       óD   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z‡  Z	S )rq   c                    sd   t |tƒr
t |tƒstdƒ‚|j|jkrtd|› d|› d�ƒ‚||f| _tƒ  t||gƒ|j¡ d S )Nú)both operands have to be a LinearOperatorzcannot add ú and ú: shape mismatch)rA   r   r    r!   r   r   r#   r    ©r"   r“   ÚBr   r   r   r#   ¶  s   
ÿ
z_SumLinearOperator.__init__c                 C   ó    | j d  |¡| j d  |¡ S ©Nr   r0   ©r   r(   r=   r   r   r   r   ¿  ó    z_SumLinearOperator._matvecc                 C   r§   r¨   ©r   rJ   r=   r   r   r   rI   Â  rª   z_SumLinearOperator._rmatvecc                 C   r§   r¨   ©r   rW   r=   r   r   r   rK   Å  rª   z_SumLinearOperator._rmatmatc                 C   r§   r¨   ©r   r<   r=   r   r   r   r   È  rª   z_SumLinearOperator._matmatc                 C   s   | j \}}|j|j S rX   ©r   rO   r¥   r   r   r   rL   Ë  ó   
z_SumLinearOperator._adjoint©
rw   r‚   rƒ   r#   r   rI   rK   r   rL   r‡   r   r   r   r   rq   µ  s    	rq   c                       r¡   )rd   c                    sz   t |tƒr
t |tƒstdƒ‚|jd |jd kr#td|› d|› d�ƒ‚tƒ  t||gƒ|jd |jd f¡ ||f| _d S )Nr¢   r0   r   zcannot multiply r£   r¤   )rA   r   r    r!   r   r#   r    r   r¥   r   r   r   r#   Ñ  s   
ÿÿz_ProductLinearOperator.__init__c                 C   ó   | j d  | j d  |¡¡S r¨   r©   r=   r   r   r   r   Û  ó   z_ProductLinearOperator._matvecc                 C   r±   ©Nr0   r   r«   r=   r   r   r   rI   Þ  r²   z_ProductLinearOperator._rmatvecc                 C   r±   r³   r¬   r=   r   r   r   rK   á  r²   z_ProductLinearOperator._rmatmatc                 C   r±   r¨   r­   r=   r   r   r   r   ä  r²   z_ProductLinearOperator._matmatc                 C   s   | j \}}|j|j S rX   r®   r¥   r   r   r   rL   ç  r¯   z_ProductLinearOperator._adjointr°   r   r   r   r   rd   Ð  s    
rd   c                       r¡   )r_   c                    sp   t |tƒs	tdƒ‚t |¡stdƒ‚t |tƒr |j\}}|| }t|gt|ƒgƒ}t	ƒ  
||j¡ ||f| _d S )NúLinearOperator expected as Azscalar expected as alpha)rA   r   r    r   r^   r_   r   r    r   r   r#   r!   )r"   r“   ÚalphaÚalpha_originalr   r   r   r   r#   í  s   



z_ScaledLinearOperator.__init__c                 C   ó   | j d | j d  |¡ S r³   r©   r=   r   r   r   r   ý  ó   z_ScaledLinearOperator._matvecc                 C   ó    t  | jd ¡| jd  |¡ S r³   )r   r™   r   rJ   r=   r   r   r   rI      rª   z_ScaledLinearOperator._rmatvecc                 C   r¹   r³   )r   r™   r   rW   r=   r   r   r   rK     rª   z_ScaledLinearOperator._rmatmatc                 C   r·   r³   r­   r=   r   r   r   r     r¸   z_ScaledLinearOperator._matmatc                 C   s   | j \}}|jt |¡ S rX   )r   rO   r   r™   )r"   r“   rµ   r   r   r   rL   	  s   
z_ScaledLinearOperator._adjointr°   r   r   r   r   r_   ì  s    r_   c                       sL   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	‡  Z
S )rl   c                    sp   t |tƒs	tdƒ‚|jd |jd krtd|›�ƒ‚t|ƒr"|dk r&tdƒ‚tƒ  t|gƒ|j¡ ||f| _d S )Nr´   r   r0   z$square LinearOperator expected, got z"non-negative integer expected as p)	rA   r   r    r!   r   r   r#   r    r   ©r"   r“   rn   r   r   r   r#     s   
z_PowerLinearOperator.__init__c                 C   s.   t j|dd�}t| jd ƒD ]}||ƒ}q|S )NT)Úcopyr0   )r   ÚarrayÚranger   )r"   Úfunr>   ÚresÚir   r   r   Ú_power  s   
z_PowerLinearOperator._powerc                 C   ó   |   | jd j|¡S ©Nr   )rÁ   r   r(   r=   r   r   r   r      ó   z_PowerLinearOperator._matvecc                 C   rÂ   rÃ   )rÁ   r   rJ   r=   r   r   r   rI   #  rÄ   z_PowerLinearOperator._rmatvecc                 C   rÂ   rÃ   )rÁ   r   rW   r=   r   r   r   rK   &  rÄ   z_PowerLinearOperator._rmatmatc                 C   rÂ   rÃ   )rÁ   r   r<   r=   r   r   r   r   )  rÄ   z_PowerLinearOperator._matmatc                 C   s   | j \}}|j| S rX   r®   rº   r   r   r   rL   ,  s   

z_PowerLinearOperator._adjoint)rw   r‚   rƒ   r#   rÁ   r   rI   rK   r   rL   r‡   r   r   r   r   rl     s    rl   c                       s,   e Zd Z‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚMatrixLinearOperatorc                    s*   t ƒ  |j|j¡ || _d | _|f| _d S rX   )r   r#   r   r!   r“   Ú_MatrixLinearOperator__adjr   )r"   r“   r   r   r   r#   2  s   zMatrixLinearOperator.__init__c                 C   r–   rX   )r“   r[   r:   r   r   r   r   8  ru   zMatrixLinearOperator._matmatc                 C   s   | j d u rt| jƒ| _ | j S rX   )rÆ   Ú_AdjointMatrixOperatorr“   r5   r   r   r   rL   ;  s   
zMatrixLinearOperator._adjoint)rw   r‚   rƒ   r#   r   rL   r‡   r   r   r   r   rÅ   1  s    rÅ   c                   @   s(   e Zd Zdd„ Zedd„ ƒZdd„ ZdS )rÇ   c                 C   s.   |j  ¡ | _|f| _|jd |jd f| _d S r³   )r9   r™   r“   r   r!   )r"   Úadjoint_arrayr   r   r   r#   B  s   z_AdjointMatrixOperator.__init__c                 C   s   | j d jS rÃ   )r   r   r5   r   r   r   r   G  s   z_AdjointMatrixOperator.dtypec                 C   s   t | jd ƒS rÃ   )rÅ   r   r5   r   r   r   rL   K  s   z_AdjointMatrixOperator._adjointN)rw   r‚   rƒ   r#   r†   r   rL   r   r   r   r   rÇ   A  s
    
rÇ   c                       sF   e Zd Zd‡ fdd„	Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z‡  Z	S )ÚIdentityOperatorNc                    s   t ƒ  ||¡ d S rX   )r   r#   )r"   r!   r   r   r   r   r#   P  s   zIdentityOperator.__init__c                 C   ó   |S rX   r   r=   r   r   r   r   S  ó   zIdentityOperator._matvecc                 C   rÊ   rX   r   r=   r   r   r   rI   V  rË   zIdentityOperator._rmatvecc                 C   rÊ   rX   r   r=   r   r   r   rK   Y  rË   zIdentityOperator._rmatmatc                 C   rÊ   rX   r   r=   r   r   r   r   \  rË   zIdentityOperator._matmatc                 C   s   | S rX   r   r5   r   r   r   rL   _  rË   zIdentityOperator._adjointrX   r°   r   r   r   r   rÉ   O  s    rÉ   c                 C   sÖ   t | tƒr| S t | tjƒst | tjƒr(| jdkrtdƒ‚t t | ¡¡} t	| ƒS t
| ƒs0t| ƒr4t	| ƒS t| dƒrgt| dƒrgd}d}d}t| dƒrL| j}t| dƒrT| j}t| dƒr\| j}t| j| j|||d	�S td
ƒ‚)aÿ  Return A as a LinearOperator.

    'A' may be any of the following types:
     - ndarray
     - matrix
     - sparse array (e.g. csr_array, lil_array, etc.)
     - LinearOperator
     - An object with .shape and .matvec attributes

    See the LinearOperator documentation for additional information.

    Notes
    -----
    If 'A' has no .dtype attribute, the data type is determined by calling
    :func:`LinearOperator.matvec()` - set the .dtype attribute to prevent this
    call upon the linear operator creation.

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.sparse.linalg import aslinearoperator
    >>> M = np.array([[1,2,3],[4,5,6]], dtype=np.int32)
    >>> aslinearoperator(M)
    <2x3 MatrixLinearOperator with dtype=int32>
    r	   zarray must have ndim <= 2r!   r(   NrJ   rW   r   )rJ   rW   r   ztype not understood)rA   r   r   ÚndarrayrB   rC   r    Ú
atleast_2dr'   rÅ   r   r   rM   rJ   rW   r   r!   r(   rS   )r“   rJ   rW   r   r   r   r   r   c  s.   




ÿrX   )r„   r   Únumpyr   Úscipy.sparser   Úscipy.sparse._sputilsr   r   r   r   Ú__all__r   r   r   r�   r    rq   rd   r_   rl   rÅ   rÇ   rÉ   r   r   r   r   r   Ú<module>   s.    ,    .
	"#