o
    `^hq                     @   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__ \/home/air/shanriGPT/back/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 )zInitialize 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 )zDefault 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   s    t | jtjkr
t| j|S )z6Default implementation of _rmatvec; defers to adjoint.)r   _adjointr   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<   I  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   rN   rO   zfUnable to multiply a LinearOperator with a sparse matrix. Wrap the matrix in aslinearoperator() first.N)r   r   r   r@   rC   r    r!   _rmatmatrP   rQ   rA   rB   r   rR   r   r   r   rmatmatx  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   rK   r   r   r8   r9   rM   r<   r:   r   r5   r   rU     s   zLinearOperator._rmatmatc                 C   s   | | S Nr   r=   r   r   r   __call__  s   zLinearOperator.__call__c                 C   
   |  |S rW   )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   rZ     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   rd   re   )r   r]   r    __rmul__r_   r   r   r   __rmatmul__  rg   zLinearOperator.__rmatmul__c                 C   s   t |r
t| |S | |S rW   )r   r]   r^   _rdotr=   r   r   r   rh     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   rb   )rA   r   rc   r   r]   r^   r   r   r'   rC   r!   r9   r(   r<   r    r=   r   r   r   rj     s   




"
zLinearOperator._rdotc                 C   s   t |r
t| |S tS rW   )r   r]   _PowerLinearOperatorNotImplemented)r"   pr   r   r   __pow__     

zLinearOperator.__pow__c                 C   s   t |tr
t| |S tS rW   )rA   r   _SumLinearOperatorrl   r=   r   r   r   __add__  ro   zLinearOperator.__add__c                 C   s
   t | dS )Nr$   )r^   r5   r   r   r   __neg__  r\   zLinearOperator.__neg__c                 C   s   |  | S rW   )rq   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.
        )rK   r5   r   r   r   adjoint)  s   zLinearOperator.adjointc                 C   ry   )zTranspose 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   rK   E     zLinearOperator._adjointc                 C   r}   )z? Default implementation of _transpose; defers to rmatvec + conj)_TransposedLinearOperatorr5   r   r   r   r{   I  r   zLinearOperator._transpose)&rv   
__module____qualname____doc__rC   __array_ufunc__r   r#   r-   r   r   r(   rJ   rI   r<   rV   rU   rX   r[   ra   rZ   rf   ri   rh   rj   rn   rq   rr   rs   rx   rz   propertyrM   r|   r9   rK   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   rV   r   r   r   r#   Q  s   z_CustomLinearOperator.__init__c                        | j d ur
|  |S t |S rW   )r   r   r   r:   r   r   r   r   ^     

z_CustomLinearOperator._matmatc                 C   rY   rW   )r   r=   r   r   r   r   d  r\   z_CustomLinearOperator._matvecc                 C   s    | j }|d u rtd|  |S )Nzrmatvec is not defined)r   rL   )r"   r>   funcr   r   r   rI   g  s   
z_CustomLinearOperator._rmatvecc                    r   rW   )r   r   rU   r:   r   r   r   rU   m  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<   rV   r   )r   r!   r   r   r   r   r   r5   r   r   r   rK   s  s   z_CustomLinearOperator._adjoint)NNNN)rv   r   r   r   r#   r   r   rI   rU   rK   r   r   r   r   r   r   N  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 rW   )r   rI   r=   r   r   r   r     rt   z_AdjointLinearOperator._matvecc                 C   r   rW   )r   r   r=   r   r   r   rI     rt   z_AdjointLinearOperator._rmatvecc                 C   r   rW   )r   rU   r=   r   r   r   r     rt   z_AdjointLinearOperator._matmatc                 C   r   rW   )r   r   r=   r   r   r   rU     rt   z_AdjointLinearOperator._rmatmat
rv   r   r   r   r#   r   rI   r   rU   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 rW   )r   conjr   rI   r=   r   r   r   r        z!_TransposedLinearOperator._matvecc                 C   r   rW   )r   r   r   r   r=   r   r   r   rI        z"_TransposedLinearOperator._rmatvecc                 C   r   rW   )r   r   r   rU   r=   r   r   r   r     r   z!_TransposedLinearOperator._matmatc                 C   r   rW   )r   r   r   r   r=   r   r   r   rU     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   )hasattr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 )rp   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   rV   r=   r   r   r   rU     r   z_SumLinearOperator._rmatmatc                 C   r   r   r   r<   r=   r   r   r   r     r   z_SumLinearOperator._matmatc                 C   s   | j \}}|j|j S rW   r   rM   r   r   r   r   rK        
z_SumLinearOperator._adjoint
rv   r   r   r#   r   rI   rU   r   rK   r   r   r   r   r   rp     s    	rp   c                       r   )rc   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   rU     r   z_ProductLinearOperator._rmatmatc                 C   r   r   r   r=   r   r   r   r     r   z_ProductLinearOperator._matmatc                 C   s   | j \}}|j|j S rW   r   r   r   r   r   rK     r   z_ProductLinearOperator._adjointr   r   r   r   r   rc     s    
rc   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   rV   r=   r   r   r   rU     r   z_ScaledLinearOperator._rmatmatc                 C   r   r   r   r=   r   r   r   r     r   z_ScaledLinearOperator._matmatc                 C   s   | j \}}|jt| S rW   )r   rM   r   r   )r"   r   r   r   r   r   rK     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 )rk   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   rm   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   rV   r=   r   r   r   rU   "  r   z_PowerLinearOperator._rmatmatc                 C   r   r   )r   r   r<   r=   r   r   r   r   %  r   z_PowerLinearOperator._matmatc                 C   s   | j \}}|j| S rW   r   r   r   r   r   rK   (  s   

z_PowerLinearOperator._adjoint)rv   r   r   r#   r   r   rI   rU   r   rK   r   r   r   r   r   rk   
  s    rk   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 rW   )r   r#   r   r!   r   _MatrixLinearOperator__adjr   )r"   r   r   r   r   r#   .  s   zMatrixLinearOperator.__init__c                 C   r   rW   )r   rZ   r:   r   r   r   r   4  rt   zMatrixLinearOperator._matmatc                 C   s   | j d u r
t| | _ | j S rW   )r   _AdjointMatrixOperatorr5   r   r   r   rK   7  s   

zMatrixLinearOperator._adjoint)rv   r   r   r#   r   rK   r   r   r   r   r   r   -  s    r   c                   @   s(   e Zd Zdd Zedd Zdd ZdS )r   c                 C   s6   |j j | _ || _|f| _|jd |jd f| _d S r   )r   r9   r   _AdjointMatrixOperator__adjointr   r!   )r"   rz   r   r   r   r#   =  s   z_AdjointMatrixOperator.__init__c                 C   s   | j jS rW   )r   r   r5   r   r   r   r   C  r   z_AdjointMatrixOperator.dtypec                 C   s   | j S rW   )r   r5   r   r   r   rK   G  s   z_AdjointMatrixOperator._adjointN)rv   r   r   r#   r   r   rK   r   r   r   r   r   <  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 rW   )r   r#   )r"   r!   r   r   r   r   r#   L  s   zIdentityOperator.__init__c                 C      |S rW   r   r=   r   r   r   r   O     zIdentityOperator._matvecc                 C   r   rW   r   r=   r   r   r   rI   R  r   zIdentityOperator._rmatvecc                 C   r   rW   r   r=   r   r   r   rU   U  r   zIdentityOperator._rmatmatc                 C   r   rW   r   r=   r   r   r   r   X  r   zIdentityOperator._matmatc                 C   s   | S rW   r   r5   r   r   r   rK   [  r   zIdentityOperator._adjointrW   r   r   r   r   r   r   K  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   rV   r   )rJ   rV   r   ztype not understood)rA   r   r   ndarrayrB   rC   r    
atleast_2dr'   r   r   r   r   rJ   rV   r   r!   r(   rQ   )r   rJ   rV   r   r   r   r   r   _  s.   




rW   )r   r   numpyr   scipy.sparser   scipy.sparse._sputilsr   r   r   r   __all__r   r   r~   r   r   rp   rc   r^   rk   r   r   r   r   r   r   r   r   <module>   s.    ,    .
	"#