
    !YHhr                     B   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      Z G d d	e      Z G d
 de      Z G d de      ZddZ G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Zd Zy)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                        e Zd ZdZdZdZ fdZd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z ee      Z d Z! ee!      Z"d Z#d Z$ x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                 ,   | t         u rt        | 	  t              S t        | 	  |       }t	        |      j
                  t         j
                  k(  rBt	        |      j                  t         j                  k(  rt        j                  dt        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__s       W/var/www/html/planif/env/lib/python3.12/site-packages/scipy/sparse/linalg/_interface.pyr   zLinearOperator.__new__   sx    . 7?#899'/#&CS	!!^%;%;;S	))^-C-CC F'5!E J    c                     |t        j                  |      }t        |      }t        |      st	        d|d      || _        || _        y)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$   s      r   __init__zLinearOperator.__init__   sI     HHUOEeu~~eYnEFF

r   c                 H   | j                   it        j                  | j                  d   t        j                        }	 t        j
                  | j                  |            }|j                   | _         yy# t        $ r! t        j                   t              | _         Y yw xY w)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_vs      r   _init_dtypezLinearOperator._init_dtype   sw     ::Brww7A,::dkk!n5
 &^^
  ! +XXc]
+s    $A7 7'B! B!c                     t        j                  |j                  D cg c]#  }| j                  |j	                  dd            % c}      S c c}w )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).
        r(      )r    hstackTr,   reshaper%   Xcols      r   r   zLinearOperator._matmat   s9     yyACCHS$++ckk"Q&78HIIHs   (Ac                 D    | j                  |j                  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(   r3   )matmatr6   r%   xs     r   r   zLinearOperator._matvec   s     {{199R+,,r   c                    t        j                  |      }| j                  \  }}|j                  |fk7  r|j                  |dfk7  rt        d      | j	                  |      }t        |t         j                        rt        |      }nt        j                  |      }|j                  dk(  r|j                  |      }|S |j                  dk(  r|j                  |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.

        r3   dimension mismatchr   z/invalid shape returned by user-defined matvec())r    
asanyarrayr$   r#   r   
isinstancematrixr   r+   ndimr6   r%   r=   MNys        r   r,   zLinearOperator.matvec   s    0 MM!jj!77qd?qww1Q%/122LLOa#A

1A66Q;		!A  VVq[		!AA  NOOr   c                    t        j                  |      }| j                  \  }}|j                  |fk7  r|j                  |dfk7  rt        d      | j	                  |      }t        |t         j                        rt        |      }nt        j                  |      }|j                  dk(  r|j                  |      }|S |j                  dk(  r|j                  |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.

        r3   r?   r   z0invalid shape returned by user-defined rmatvec())r    r@   r$   r#   _rmatvecrA   rB   r   r+   rC   r6   rD   s        r   rmatveczLinearOperator.rmatvec  s    0 MM!jj!77qd?qww1Q%/122MM!a#A

1A66Q;		!A  VVq[		!AA  OPPr   c                 T   t        |       j                  t        j                  k(  rht        | d      rVt        |       j                  t        j                  k7  r0| j	                  |j                  dd            j                  d      S t        | j                  j                  |      S )z6Default implementation of _rmatvec; defers to adjoint._rmatmatr(   r3   )	r   _adjointr   hasattrrL   r6   NotImplementedErrorHr,   r<   s     r   rI   zLinearOperator._rmatvecA  sz    :."9"99j)T
++~/F/FF}}QYYr1%56>>rBB%%66==##r   c                 
   t        |      s t        |      st        j                  |      }|j                  dk7  rt        d|j                   d      |j                  d   | j                  d   k7  r%t        d| j                   d|j                         	 | j                  |      }t        |t        j                        rt        |      }|S # t        $ r(}t        |      st        |      rt        d      | d	}~ww xY w)
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   r3   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%   r8   Yes       r   r;   zLinearOperator.matmatM  s    . 1!4a A66Q;CAFF82NOO771:A&3DJJ<r!''KLL	QA a#A  	{03B  	s   C 	D#C==Dc                    t        |      s t        |      st        j                  |      }|j                  dk7  rt        d|j                  z        |j                  d   | j                  d   k7  r%t        d| j                   d|j                         	 | j                  |      }t        |t        j                        rt        |      }|S # t        $ r(}t        |      st        |      rt        d      | d}~ww xY w)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   rR   rS   zfUnable to multiply a LinearOperator with a sparse matrix. Wrap the matrix in aslinearoperator() first.N)r   r   r    r@   rC   r#   r$   rL   rT   rU   rA   rB   r   rV   s       r   rmatmatzLinearOperator.rmatmat|  s    , 1!4a A66Q;G vv& ' ' 771:A&3DJJ<r!''KLL	a A a#A  	{03D  	s   C 	D#C<<Dc                 &   t        |       j                  t        j                  k(  rLt        j                  |j
                  D cg c]#  }| j                  |j                  dd            % c}      S | j                  j                  |      S c c}w )z@Default implementation of _rmatmat defers to rmatvec or adjoint.r(   r3   )
r   rM   r   r    r4   r5   rJ   r6   rP   r;   r7   s      r   rL   zLinearOperator._rmatmat  se    :."9"9999!##N3dll3;;r1+=>NOO66==## Os   (Bc                     | |z  S N r<   s     r   __call__zLinearOperator.__call__  s    Avr   c                 $    | j                  |      S r]   )dotr<   s     r   __mul__zLinearOperator.__mul__  s    xx{r   c                 `    t        j                  |      st        d      t        | d|z        S )Nz.Can only divide a linear operator by a scalar.g      ?)r    isscalarr#   _ScaledLinearOperatorr%   others     r   __truediv__zLinearOperator.__truediv__  s+    {{5!MNN$T3u955r   c                    t        |t              rt        | |      S t        j                  |      rt        | |      S t        |      s t        |      st        j                  |      }|j                  dk(  s!|j                  dk(  r#|j                  d   dk(  r| j                  |      S |j                  dk(  r| j                  |      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.

        r3   r   )expected 1-d or 2-d array or matrix, got )rA   r   _ProductLinearOperatorr    rd   re   r   r   r+   rC   r$   r,   r;   r#   r<   s     r   ra   zLinearOperator.dot  s     a()$22[[^(q11A;'9!'<JJqMvv{affkaggajAo{{1~%1{{1~% #LQE!RSSr   c                 d    t        j                  |      rt        d      | j                  |      S Nz0Scalar operands are not allowed, use '*' instead)r    rd   r#   rb   rf   s     r   
__matmul__zLinearOperator.__matmul__  s/    ;;u / 0 0||E""r   c                 d    t        j                  |      rt        d      | j                  |      S rm   )r    rd   r#   __rmul__rf   s     r   __rmatmul__zLinearOperator.__rmatmul__  s/    ;;u / 0 0}}U##r   c                 f    t        j                  |      rt        | |      S | j                  |      S r]   )r    rd   re   _rdotr<   s     r   rp   zLinearOperator.__rmul__  s(    ;;q>(q11::a= r   c                 (   t        |t              rt        ||       S t        j                  |      rt        | |      S t        |      s t        |      st        j                  |      }|j                  dk(  s!|j                  dk(  rA|j                  d   dk(  r/| j                  j                  |j                        j                  S |j                  dk(  r/| j                  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.
        r3   r   r   rj   )rA   r   rk   r    rd   re   r   r   r+   rC   r$   r5   r,   r;   r#   r<   s     r   rs   zLinearOperator._rdot  s    $ a()!T22[[^(q11A;'9!'<JJqM vv{affkaggajAovv}}QSS)+++1vv}}QSS)+++ #LQE!RSSr   c                 P    t        j                  |      rt        | |      S t        S r]   )r    rd   _PowerLinearOperatorNotImplemented)r%   ps     r   __pow__zLinearOperator.__pow__  s     ;;q>'a00!!r   c                 F    t        |t              rt        | |      S t        S r]   )rA   r   _SumLinearOperatorrw   r<   s     r   __add__zLinearOperator.__add__  s    a(%dA..!!r   c                     t        | d      S )Nr(   )re   r%   s    r   __neg__zLinearOperator.__neg__  s    $T2..r   c                 &    | j                  |       S r]   )r|   r<   s     r   __sub__zLinearOperator.__sub__!  s    ||QBr   c                     | j                   \  }}| j                  d}ndt        | j                        z   }d||| j                  j                  |fz  S )Nzunspecified dtypezdtype=z<%dx%d %s with %s>)r$   r!   strr   __name__)r%   rE   rF   dts       r   __repr__zLinearOperator.__repr__$  sN    jj!::$BC

O+B#q!T^^-D-Db&IIIr   c                 "    | j                         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.
        )rM   r~   s    r   adjointzLinearOperator.adjoint-  s     }}r   c                 "    | j                         S )zTranspose this linear operator.

        Returns a LinearOperator that represents the transpose of this one.
        Can be abbreviated self.T instead of self.transpose().
        )
_transposer~   s    r   	transposezLinearOperator.transpose?  s       r   c                     t        |       S )z6Default implementation of _adjoint; defers to rmatvec.)_AdjointLinearOperatorr~   s    r   rM   zLinearOperator._adjointI  s    %d++r   c                     t        |       S )z? Default implementation of _transpose; defers to rmatvec + conj)_TransposedLinearOperatorr~   s    r   r   zLinearOperator._transposeM  s    (..r   )&r   
__module____qualname____doc__rC   __array_ufunc__r   r&   r1   r   r   r,   rJ   rI   r;   rZ   rL   r_   rb   rh   ra   rn   rq   rp   rs   ry   r|   r   r   r   r   propertyrP   r   r5   rM   r   __classcell__r   s   @r   r   r   7   s    \| DO ,*J
--^-^
$-^,\$6T>#$!"TH""/ J  	A! 	A,/r   c                   N     e Zd ZdZ	 	 d fd	Z fdZd Zd Z fdZd Z	 xZ
S )	r   z>Linear operator defined in terms of user-specified operations.c                     t         |   ||       d| _        || _        || _        || _        || _        | j                          y )Nr^   )r   r&   r   "_CustomLinearOperator__matvec_impl#_CustomLinearOperator__rmatvec_impl#_CustomLinearOperator__rmatmat_impl"_CustomLinearOperator__matmat_implr1   )r%   r$   r,   rJ   r;   r!   rZ   r   s          r   r&   z_CustomLinearOperator.__init__U  sE    &	#%%#r   c                 \    | j                   | j                  |      S t        | 	  |      S r]   )r   r   r   r%   r8   r   s     r   r   z_CustomLinearOperator._matmatb  s/    )%%a((7?1%%r   c                 $    | j                  |      S r]   )r   r<   s     r   r   z_CustomLinearOperator._matvech  s    !!!$$r   c                 V    | j                   }|t        d      | j                  |      S )Nzrmatvec is not defined)r   rO   )r%   r=   funcs      r   rI   z_CustomLinearOperator._rmatveck  s/    ""<%&>??""1%%r   c                 \    | j                   | j                  |      S t        | 	  |      S r]   )r   r   rL   r   s     r   rL   z_CustomLinearOperator._rmatmatq  s0    *&&q))7#A&&r   c                     t        | j                  d   | j                  d   f| j                  | j                  | j                  | j
                  | j                        S )Nr3   r   )r$   r,   rJ   r;   rZ   r!   )r   r$   r   r   r   r   r!   r~   s    r   rM   z_CustomLinearOperator._adjointw  sQ    $DJJqM4::a=+I,0,?,?-1-?-?,0,?,?-1-?-?+/::7 	7r   )NNNN)r   r   r   r   r&   r   r   rI   rL   rM   r   r   s   @r   r   r   R  s*    H;?%)&%&'7r   r   c                   :     e Zd ZdZ fdZd Zd Zd Zd Z xZ	S )r   z$Adjoint of arbitrary Linear Operatorc                     |j                   d   |j                   d   f}t        | 	  |j                  |       || _        |f| _        y Nr3   r   )r!   r$   r$   r   r&   r!   Ar   r%   r   r$   r   s      r   r&   z_AdjointLinearOperator.__init__  C    QWWQZ(qwwe4D	r   c                 8    | j                   j                  |      S r]   )r   rI   r<   s     r   r   z_AdjointLinearOperator._matvec      vvq!!r   c                 8    | j                   j                  |      S r]   )r   r   r<   s     r   rI   z_AdjointLinearOperator._rmatvec      vv~~a  r   c                 8    | j                   j                  |      S r]   )r   rL   r<   s     r   r   z_AdjointLinearOperator._matmat  r   r   c                 8    | j                   j                  |      S r]   )r   r   r<   s     r   rL   z_AdjointLinearOperator._rmatmat  r   r   
r   r   r   r   r&   r   rI   r   rL   r   r   s   @r   r   r     s    ."!"!r   r   c                   :     e Zd ZdZ fdZd Zd Zd Zd Z xZ	S )r   z*Transposition of arbitrary Linear Operatorc                     |j                   d   |j                   d   f}t        | 	  |j                  |       || _        |f| _        y r   r   r   s      r   r&   z"_TransposedLinearOperator.__init__  r   r   c                     t        j                  | j                  j                  t        j                  |                  S r]   )r    conjr   rI   r<   s     r   r   z!_TransposedLinearOperator._matvec  &    wwtvvrwwqz233r   c                     t        j                  | j                  j                  t        j                  |                  S r]   )r    r   r   r   r<   s     r   rI   z"_TransposedLinearOperator._rmatvec  &    wwtvv~~bggaj122r   c                     t        j                  | j                  j                  t        j                  |                  S r]   )r    r   r   rL   r<   s     r   r   z!_TransposedLinearOperator._matmat  r   r   c                     t        j                  | j                  j                  t        j                  |                  S r]   )r    r   r   r   r<   s     r   rL   z"_TransposedLinearOperator._rmatmat  r   r   r   r   s   @r   r   r     s    44343r   r   c                     |g }| D ]-  }|t        |d      s|j                  |j                         / t        j                  | S )Nr!   )rN   appendr!   r    result_type)	operatorsdtypesr   s      r   
_get_dtyper     sJ    ~ %?wsG4MM#))$% >>6""r   c                   <     e Zd Z fdZd Zd Zd Zd Zd Z xZ	S )r{   c                    t        |t              rt        |t              st        d      |j                  |j                  k7  rt        d| d| d      ||f| _        t
        |   t        ||g      |j                         y )N)both operands have to be a LinearOperatorzcannot add  and : shape mismatch)rA   r   r#   r$   r   r   r&   r   r%   r   Br   s      r   r&   z_SumLinearOperator.__init__  su    !^,q.1HII77agg{1#U1#5EFGGF	QF+QWW5r   c                 |    | j                   d   j                  |      | j                   d   j                  |      z   S Nr   r3   r   r,   r<   s     r   r   z_SumLinearOperator._matvec  3    yy|""1%		!(;(;A(>>>r   c                 |    | j                   d   j                  |      | j                   d   j                  |      z   S r   r   rJ   r<   s     r   rI   z_SumLinearOperator._rmatvec  3    yy|##A&1)=)=a)@@@r   c                 |    | j                   d   j                  |      | j                   d   j                  |      z   S r   r   rZ   r<   s     r   rL   z_SumLinearOperator._rmatmat  r   r   c                 |    | j                   d   j                  |      | j                   d   j                  |      z   S r   r   r;   r<   s     r   r   z_SumLinearOperator._matmat  r   r   c                 R    | j                   \  }}|j                  |j                  z   S r]   r   rP   r%   r   r   s      r   rM   z_SumLinearOperator._adjoint  !    yy1ssQSSyr   
r   r   r   r&   r   rI   rL   r   rM   r   r   s   @r   r{   r{     s#    6?AA?r   r{   c                   <     e Zd Z fdZd Zd Zd Zd Zd Z xZ	S )rk   c                 >   t        |t              rt        |t              st        d      |j                  d   |j                  d   k7  rt        d| d| d      t        |   t        ||g      |j                  d   |j                  d   f       ||f| _        y )Nr   r3   r   zcannot multiply r   r   )rA   r   r#   r$   r   r&   r   r   r   s      r   r&   z_ProductLinearOperator.__init__  s    !^,q.1HII771:#/s%s:JKLLQF+67ggaj!''!*5M	OF	r   c                 v    | j                   d   j                  | j                   d   j                  |            S r   r   r<   s     r   r   z_ProductLinearOperator._matvec  .    yy|""499Q<#6#6q#9::r   c                 v    | j                   d   j                  | j                   d   j                  |            S Nr3   r   r   r<   s     r   rI   z_ProductLinearOperator._rmatvec  .    yy|##DIIaL$8$8$;<<r   c                 v    | j                   d   j                  | j                   d   j                  |            S r   r   r<   s     r   rL   z_ProductLinearOperator._rmatmat  r   r   c                 v    | j                   d   j                  | j                   d   j                  |            S r   r   r<   s     r   r   z_ProductLinearOperator._matmat  r   r   c                 R    | j                   \  }}|j                  |j                  z  S r]   r   r   s      r   rM   z_ProductLinearOperator._adjoint  r   r   r   r   s   @r   rk   rk     s!    ;==;r   rk   c                   <     e Zd Z fdZd Zd Zd Zd Zd Z xZ	S )re   c                 8   t        |t              st        d      t        j                  |      st        d      t        |t
              r|j                  \  }}||z  }t        |gt        |      g      }t        | )  ||j                         ||f| _        y )NLinearOperator expected as Azscalar expected as alpha)rA   r   r#   r    rd   re   r   r   r   r   r&   r$   )r%   r   alphaalpha_originalr!   r   s        r   r&   z_ScaledLinearOperator.__init__  s    !^,;<<{{5!788a./ !A~ N*EA3e.(J	r   c                 ^    | j                   d   | j                   d   j                  |      z  S r   r   r<   s     r   r   z_ScaledLinearOperator._matvec  (    yy|diil11!444r   c                     t        j                  | j                  d         | j                  d   j                  |      z  S r   )r    r   r   rJ   r<   s     r   rI   z_ScaledLinearOperator._rmatvec   1    wwtyy|$tyy|';';A'>>>r   c                     t        j                  | j                  d         | j                  d   j                  |      z  S r   )r    r   r   rZ   r<   s     r   rL   z_ScaledLinearOperator._rmatmat  r   r   c                 ^    | j                   d   | j                   d   j                  |      z  S r   r   r<   s     r   r   z_ScaledLinearOperator._matmat  r   r   c                 d    | j                   \  }}|j                  t        j                  |      z  S r]   )r   rP   r    r   )r%   r   r   s      r   rM   z_ScaledLinearOperator._adjoint	  s&    995ssRWWU^##r   r   r   s   @r   re   re     s!     5??5$r   re   c                   B     e Zd Z fdZd Zd Zd Zd Zd Zd Z	 xZ
S )rv   c                 &   t        |t              st        d      |j                  d   |j                  d   k7  rt        d|      t	        |      r|dk  rt        d      t
        |   t        |g      |j                         ||f| _        y )Nr   r   r3   z$square LinearOperator expected, got z"non-negative integer expected as p)	rA   r   r#   r$   r   r   r&   r   r   )r%   r   rx   r   s      r   r&   z_PowerLinearOperator.__init__  s    !^,;<<771:#CA5IJJ|q1uABBQC!''2F	r   c                 ~    t        j                  |d      }t        | j                  d         D ]
  } ||      } |S )NT)copyr3   )r    arrayranger   )r%   funr=   resis        r   _powerz_PowerLinearOperator._power  s<    hhqt$tyy|$ 	Ac(C	
r   c                 T    | j                  | j                  d   j                  |      S Nr   )r   r   r,   r<   s     r   r   z_PowerLinearOperator._matvec   !    {{499Q<..22r   c                 T    | j                  | j                  d   j                  |      S r   )r   r   rJ   r<   s     r   rI   z_PowerLinearOperator._rmatvec#  !    {{499Q<//33r   c                 T    | j                  | j                  d   j                  |      S r   )r   r   rZ   r<   s     r   rL   z_PowerLinearOperator._rmatmat&  r   r   c                 T    | j                  | j                  d   j                  |      S r   )r   r   r;   r<   s     r   r   z_PowerLinearOperator._matmat)  r   r   c                 >    | j                   \  }}|j                  |z  S r]   r   )r%   r   rx   s      r   rM   z_PowerLinearOperator._adjoint,  s    yy1ssaxr   )r   r   r   r&   r   r   rI   rL   r   rM   r   r   s   @r   rv   rv     s&    	3443r   rv   c                   *     e Zd Z fdZd Zd Z xZS )MatrixLinearOperatorc                 z    t         |   |j                  |j                         || _        d | _        |f| _        y r]   )r   r&   r!   r$   r   _MatrixLinearOperator__adjr   )r%   r   r   s     r   r&   zMatrixLinearOperator.__init__2  s1    !''*
D	r   c                 8    | j                   j                  |      S r]   )r   ra   )r%   r8   s     r   r   zMatrixLinearOperator._matmat8  s    vvzz!}r   c                 f    | j                   t        | j                        | _         | j                   S r]   )r  _AdjointMatrixOperatorr   r~   s    r   rM   zMatrixLinearOperator._adjoint;  s&    ::/7DJzzr   )r   r   r   r&   r   rM   r   r   s   @r   r  r  1  s    r   r  c                   (    e Zd Zd Zed        Zd Zy)r  c                     |j                   j                         | _        |f| _        |j                  d   |j                  d   f| _        y r   )r5   r   r   r   r$   )r%   adjoint_arrays     r   r&   z_AdjointMatrixOperator.__init__B  sB    %%'"$	"((+]-@-@-CC
r   c                 4    | j                   d   j                  S r   )r   r!   r~   s    r   r!   z_AdjointMatrixOperator.dtypeG  s    yy|!!!r   c                 2    t        | j                  d         S r   )r  r   r~   s    r   rM   z_AdjointMatrixOperator._adjointK  s    #DIIaL11r   N)r   r   r   r&   r   r!   rM   r^   r   r   r  r  A  s!    D
 " "2r   r  c                   >     e Zd Zd fd	Zd Zd Zd Zd Zd Z xZ	S )IdentityOperatorc                 &    t         |   ||       y r]   )r   r&   )r%   r$   r!   r   s      r   r&   zIdentityOperator.__init__P  s    &r   c                     |S r]   r^   r<   s     r   r   zIdentityOperator._matvecS      r   c                     |S r]   r^   r<   s     r   rI   zIdentityOperator._rmatvecV  r  r   c                     |S r]   r^   r<   s     r   rL   zIdentityOperator._rmatmatY  r  r   c                     |S r]   r^   r<   s     r   r   zIdentityOperator._matmat\  r  r   c                     | S r]   r^   r~   s    r   rM   zIdentityOperator._adjoint_  s    r   r]   r   r   s   @r   r  r  O  s!    'r   r  c                    t        | t              r| S t        | t        j                        st        | t        j                        rM| j
                  dkD  rt        d      t        j                  t        j                  |             } t        |       S t        |       st        |       rt        |       S t        | d      r~t        | d      rrd}d}d}t        | d      r| j                  }t        | d      r| j                  }t        | d      r| j                  }t        | j                   | j"                  |||	      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   rZ   r!   )rJ   rZ   r!   ztype not understood)rA   r   r    ndarrayrB   rC   r#   
atleast_2dr+   r  r   r   rN   rJ   rZ   r!   r$   r,   rU   )r   rJ   rZ   r!   s       r   r	   r	   c  s   4 !^$	Arzz	"jBII&>66A:899MM"**Q-(#A&&	!*1-#A&& 1g71h#7GGEq)$))q)$))q'"!!''188W*1@ @ 122r   r]   )r   r   numpyr    scipy.sparser   scipy.sparse._sputilsr   r   r   r   __all__r   r   r   r   r   r{   rk   re   rv   r  r  r  r	   r^   r   r   <module>r     s   *X   ! R R/
0X/ X/v+7N +7\!^ !*3 3.# 6^ 8$N $D >  F>  21 2~ (63r   