
    ^j                        d Z ddlZddlZddlZddlZddlmZ ddlm	Z
 ddlmZmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZmZmZmZ dd	gZ e        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) e       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)sparse)array_api_extra)
SCIPY_ARRAY_API_asarrayarray_namespaceis_array_api_objis_pydata_sparse_array	np_compatxp_capabilitiesxp_copyxp_isscalarxp_result_type)issparse)asmatrixis_pydata_spmatrix	isintlikeisshapeLinearOperatoraslinearoperatorc                   R    e Zd ZU dZdZ eej                        Zee	d<   e
e	d<    fdZd)dZd Zd Zd	 Zd
 Zd Zd*defdZd Zd Zd Zd*de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)e*d$        Z+d% Z,e*d&        Z-d' Z.d( Z/ xZ0S )+r   a  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, optionally with additional batch dimensions at the front)
    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.

    The defined operator may have additional "batch" dimensions
    prepended to the core shape, to represent a batch of 2-D operators;
    see :ref:`linalg_batch` for details.

    Parameters
    ----------
    shape : tuple
        Matrix dimensions ``(..., M, N)``,
        where ``...`` represents any additional batch dimensions.
    matvec : callable f(v)
        Applies ``A`` to ``v``, where ``v`` is a dense vector
        with shape ``(..., N)``.
    rmatvec : callable f(v)
        Applies ``A^H`` to ``v``, where ``A^H`` is the conjugate transpose of ``A``,
        and ``v`` is a dense vector of shape ``(..., M)``.
    matmat : callable f(V)
        Returns ``A @ V``, where ``V`` is a dense matrix
        with dimensions ``(..., N, K)``.
    rmatmat : callable f(V)
        Returns ``A^H @ V``, where ``A^H`` is the conjugate transpose of ``A``,
        and where ``V`` is a dense matrix with dimensions ``(..., M, K)``.
    dtype : dtype
        Data type of the matrix or matrices.
    xp : array_namespace, optional
        A namespace compatible with the array API standard for use in array operations.
        Default: ``numpy``.

    Attributes
    ----------
    args : tuple
        For linear operators describing products etc. of other linear
        operators, the operands of the binary operation.
    ndim : int
        Number of dimensions (greater than 2 in the case of batch dimensions).
    T : LinearOperator
        Transpose.
    H : LinearOperator
        Hermitian adjoint.

    Methods
    -------
    matvec
    matmat
    adjoint
    transpose
    rmatvec
    rmatmat
    dot
    rdot
    __mul__
    __matmul__
    __call__
    __add__
    __truediv__
    __rmul__
    __rmatmul__

    See Also
    --------
    aslinearoperator : Construct a `LinearOperator`.

    Notes
    -----
    The user-defined `matvec` function must properly handle the case
    where ``v`` has shape ``(..., N)``.

    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.
    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 raised to integral powers, 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.])

    N__class_getitem__ndimc                 ,   | 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.   )category
stacklevel)
r   super__new___CustomLinearOperatortype_matvec_matmatwarningswarnRuntimeWarning)clsargskwargsobj	__class__s       W/opt/ringagent/.cad-venv/lib/python3.12/site-packages/scipy/sparse/linalg/_interface.pyr   zLinearOperator.__new__   sy    . 7?#899'/#&C S	!!^%;%;;I%%)?)??<+ 	 J    c                 &   |t         n|}||j                  d|      j                  }t        |      }t	        |      dk  rt        d|d      t        |d      st        d|      || _        || _        t	        |      | _        || _	        y)	zInitialize this LinearOperator.

        To be called by subclasses. ``dtype`` may be None; ``shape`` should
        be convertible to a length >=2 tuple.
        Nr   dtyper   zinvalid shape z (must be at least 2-d)F)check_nd)
r
   emptyr/   tuplelen
ValueErrorr   shaper   _xp)selfr/   r5   xps       r+   __init__zLinearOperator.__init__   s     *Y"HHQeH,22Eeu:>~eY6MNOOuu-~eY788

J	r,   c                 h    | j                   j                         }|d   j                  d      |d<   |S )Nr6   r   )__dict__copyr1   r7   states     r+   __getstate__zLinearOperator.__getstate__   s1    ""$U|))!,er,   c                 x    t        |j                  d            | _        | j                  j	                  |       y )Nr6   )r   popr6   r;   updater=   s     r+   __setstate__zLinearOperator.__setstate__   s)    "599U#34U#r,   c                 Z   | j                   i| j                  }|j                  | j                  d   |j                        }	 |j                  | j                  |            }|j                   | _         yy# t        t        t        f$ r t        j                  |d      | _         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.
        Nr.   integral)r8   kind)r/   r6   zerosr5   int8asarraymatvecOverflowError	TypeErrorRuntimeErrorxpxdefault_dtype)r7   r8   vmatvec_vs       r+   _init_dtypezLinearOperator._init_dtype  s     ::BBrww7A,::dkk!n5 &^^
 
 "9l; G ..":F
Gs    A7 70B*)B*c                    | j                   }|j                  t        |j                  d         D cg c]  }| j	                  |ddd|f          c}d      S c c}w )a  Default matrix-matrix multiplication handler.

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

        Falls back to `_matvec`, so defining that will
        define matrix multiplication too (though in a very suboptimal way).
        rE   .Naxis)r6   stackranger5   r!   r7   Xr8   is       r+   r"   zLinearOperator._matmat  sX     XX xx16qwwr{1CDAT\\!CAI,'D2  
 	
Ds    Ac                 `    | j                   }| j                  |d|j                  f         d   S )al  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)`` array,
        and should return a shape ``(..., M)`` array.

        Falls back to `_matmat`, so defining that
        will define matrix-vector multiplication as well.
        ..r   )r6   r"   newaxisr7   xr8   s      r+   r!   zLinearOperator._matvec*  s.     XX||Ac2::o./77r,   adjointc                    | j                   }t        |d|      }| j                  ^ }}}|r||fn||f\  }}t        |t        j
                        rR|r| j                  |      n| j                  |      }	|j                  |dfk(  r|	j                  |d      }	t        |	      S d}
d}|j                  |dfk(  x}rj|rdnd}|rdnd	}d
| d| d| d}t        j                  |t        t        j                  j                  t               f       |j                  ||f      }n2|j"                  dk\  r#|j                  d   |k(  x}r|j                  d d }
|s"|s d| d| d|j                   }t%        |      |r| j                  |      n| j                  |      }	t'        j(                  ||
      }|r|j                  |	g ||      }	|	S |r|j                  |	g ||d      }	|	S )NTsubokr8       Fz	`rmatvec`z`matvec`z	`rmatmat`z`matmat`zCalling z  on 'column vectors' of shape `(za, 1)` was deprecated in SciPy 1.18.0 and will no longer be possible in SciPy 1.20.0. Please call z! instead for identical behaviour.)skip_file_prefixesrE   z6Dimension mismatch: `x` must have a shape ending in `(z,)`, or shape `(z, 1)`. Given shape: )r6   r   r5   
isinstancenpmatrix_rmatvecr!   reshaper   r#   r$   FutureWarningospathdirname__file__r   r4   rO   broadcast_shapes)r7   r`   ra   r8   self_broadcast_dimsMN	inner_dim	outer_dimyx_broadcast_dims
row_vectorcolumn_vector	func_namematmat_func_namemsgbroadcasted_dimss                    r+   _shared_matveczLinearOperator._shared_matvec8  s   XXQdr*%)ZZ"	a)01vq!f	9 a#$+a aAww9a.(IIi+A;,. 
GG	1~55=5'.JI.5{:9+ &K  /00QS  MM]8Q7S 

1yl+AVVq[AGGBK9,DDjD wws|mK/	{ ;  !y* 
 S/! 'DMM!T\\!_//0CEUV

1< 0<)<=A  

1? 0?)?Q?@Ar,   c                 $    | j                  |      S )a  Matrix-vector multiplication.

        Applies ``A`` to `x`, where ``A`` is an ``M`` x ``N``
        linear operator (or batch of linear operators)
        and `x` is a row vector (or batch of such vectors).

        Parameters
        ----------
        x : {matrix, ndarray}
            An array with shape ``(..., N)`` representing a row vector
            (or batch of row vectors).

            .. versionadded:: 1.18.0
                A ``FutureWarning`` is emitted for column vector input of shape
                ``(N, 1)``, for which an array with shape ``(M, 1)`` is returned.
                `matmat` can be called instead for identical behaviour on such input.

        Returns
        -------
        y : {matrix, ndarray}
            An array with shape ``(..., M)``.

        Notes
        -----
        This method wraps the user-specified ``matvec`` routine or overridden
        ``_matvec`` method to ensure that `y` has the correct shape and type.
        r   r7   r`   s     r+   rK   zLinearOperator.matveck  s    8 ""1%%r,   c                 (    | j                  |d      S )a,  Adjoint matrix-vector multiplication.

        Applies ``A^H`` to `x`, where ``A`` is an
        ``M`` x ``N`` linear operator (or batch of linear operators)
        and `x` is a row vector (or batch of such vectors).

        Parameters
        ----------
        x : {matrix, ndarray}
            An array with shape ``(..., M)`` representing a row vector
            (or batch of row vectors),
            or an array with shape ``(M, 1)`` representing a column vector.

            .. versionadded:: 1.18.0
                A ``FutureWarning`` is now emitted for column vector input of shape
                ``(M, 1)``, for which an array with shape ``(N, 1)`` is returned.
                `rmatmat` can be called instead for identical behaviour on such input.

        Returns
        -------
        y : {matrix, ndarray}
            An array with shape ``(..., N)``.

        Notes
        -----
        This method wraps the user-specified ``rmatvec`` routine or overridden
        ``_rmatvec`` method to ensure that `y` has the correct shape and type.
        Tra   r   r   s     r+   rmatveczLinearOperator.rmatvec  s    : ""1d"33r,   c                 R   t        |       j                  t        j                  k(  rgt        | d      rUt        |       j                  t        j                  k7  r/| j
                  }| j	                  |d|j                  f         d   S t        | j                  j                  |      S )zPDefault implementation of `_rmatvec`.
        Defers to `_rmatmat` or `adjoint`._rmatmat.r]   )
r    _adjointr   hasattrr   r6   r^   NotImplementedErrorHr!   r_   s      r+   rk   zLinearOperator._rmatvec  s     :."9"99 j)J''>+B+BBXX}}QsBJJ%78@@%%66>>!$$r,   c                 X   t        |      s#t        |      st        |d| j                        }|j                  dk  rt        d|j                   d      |j                  d   |r| j                  d   n| j                  d   k7  r%t        d| j                   d	|j                         	 |r| j                  |      n| j                  |      }t        |t        j                        rt        |      }|S # t        $ r(}t        |      st        |      rt        d
      | d }~ww xY w)NTrc   r   z-Expected at least 2-d ndarray or matrix, not z-drE   zDimension mismatch: z, zMultipliying LinearOperator with a sparse matrix failed. Try wrapping the matrix with `aslinearoperator` first, or ensuring the operator's `matmat` function supports sparse input.)r   r   r   r6   r   r4   r5   r   r"   	ExceptionrM   rh   ri   rj   r   )r7   rZ   ra   Yes        r+   _shared_matmatzLinearOperator._shared_matmat  s   1!4$4884A66A:LQVVHTVWXX772;W4::b>$**R.I3DJJ<r!''KLL
	$+a aA a#A  	{03.
  	s   -$C8 8	D)#D$$D)c                 $    | j                  |      S )a  Matrix-matrix multiplication.

        Performs the operation ``A @ X`` where ``A`` is an ``M`` x ``N``
        linear operator (or batch of linear operators)
        and `X` is a dense ``N`` x ``K`` matrix
        (or batch of dense matrices).

        Parameters
        ----------
        X : {matrix, ndarray}
            An array with shape ``(..., N, K)`` representing the dense matrix
            (or batch of dense matrices).

        Returns
        -------
        Y : {matrix, ndarray}
            An array with shape ``(..., M, K)``.

        Notes
        -----
        This method wraps any user-specified ``matmat`` routine or overridden
        ``_matmat`` method to ensure that `Y` has the correct type.
        r   r7   rZ   s     r+   matmatzLinearOperator.matmat  s    0 ""1%%r,   c                 (    | j                  |d      S )a   Adjoint matrix-matrix multiplication.

        Performs the operation ``A^H @ X`` where ``A`` is an ``M`` x ``N``
        linear operator (or batch of linear operators)
        and `X` is a dense ``M`` x ``K`` matrix
        (or batch of dense matrices).
        The default implementation defers to the adjoint.

        Parameters
        ----------
        X : {matrix, ndarray}
            An array with shape ``(..., M, K)`` representing the dense matrix
            (or batch of dense matrices).

        Returns
        -------
        Y : {matrix, ndarray}
            An array with shape ``(..., N, K)``.

        Notes
        -----
        This method wraps any user-specified ``rmatmat`` routine or overridden
        ``_rmatmat`` method to ensure that `Y` has the correct type.

        Tr   r   r   s     r+   rmatmatzLinearOperator.rmatmat  s    4 ""1d"33r,   c                B   t        |       j                  t        j                  k(  rZ| j                  }|j	                  t        |j                  d         D cg c]  }| j                  |ddd|f          c}d      S | j                  j                  |      S c c}w )zGDefault implementation of `_rmatmat`; defers to `rmatvec` or `adjoint`.rE   .NrU   )
r    r   r   r6   rW   rX   r5   rk   r   r"   rY   s       r+   r   zLinearOperator._rmatmat	  s    :."9"99B 886;AGGBK6HIqa|,IPR    66>>!$$ Js    Bc                     | |z  S )zIApply this linear operator.

        Equivalent to `__matmul__`.
        rf   r   s     r+   __call__zLinearOperator.__call__  s    
 axr,   c                 $    | j                  |      S )zRMultiplication.

        Used by the ``*`` operator. Equivalent to `dot`.
        )dotr   s     r+   __mul__zLinearOperator.__mul__  s    
 xx{r,   c                 d    t        |      st        d      t        | d|z  | j                        S )zKScalar Division.

        Returns a lazily scaled linear operator.
        z.Can only divide a linear operator by a scalar.g      ?r8   )r   r4   _ScaledLinearOperatorr6   r7   others     r+   __truediv__zLinearOperator.__truediv__$  s/    
 5!MNN$T3;488DDr,   c                     t        |dd       }|'t        || j                  j                  d      d      }|| j                  k7  rd| j                   d| }t	        |      y )Nr6   r   T)	sparse_okz2Mismatched array namespaces.Namespace for self is z, namespace for x is )getattrr   r6   r1   rM   )r7   r`   xp_xr~   s       r+   _check_matching_namespacez(LinearOperator._check_matching_namespace.  sm    q%&<"1dhhnnQ&74HD488))-
2GvO  C.  r,   c                 6   | j                  |       t        |t              rt        | || j                        S t        |      rt        | || j                        S t        |      s&t        |      s| j                  j                  |      }| j                  d   }|j                  |fk(  }|j                  dk\  xr |j                  d   |k(  }|s"|s d| d| d|j                   }t        |      |r| j                  |      S |r| j                  |      S y)	a  Multi-purpose multiplication method.

        Parameters
        ----------
        x : array_like or `LinearOperator` or scalar
            Array-like input will be interpreted as a 1-D row vector or
            2-D matrix (or batch of matrices)
            depending on its shape. See the Returns section for details.

        Returns
        -------
        Ax : array or `LinearOperator`
            - For `LinearOperator` input, operator composition is performed.

            - For scalar input, a lazily scaled operator is returned.

            - Otherwise, the input is expected to take the form of a dense
              1-D vector or 2-D matrix (or batch of matrices),
              interpreted as follows
              (where ``self`` is an ``M`` by ``N`` linear operator):

              - If `x` has shape ``(N,)``
                it is interpreted as a row vector
                and `matvec` is called.
              - If `x` has shape ``(..., N, K)`` for some
                integer ``K``, it is interpreted as a matrix
                (or batch of matrices if there are batch dimensions)
                and `matmat` is called.

        See Also
        --------
        __mul__ : Equivalent method used by the ``*`` operator.
        __matmul__ :
            Method used by the ``@`` operator which rejects scalar
            input before calling this method.

        Notes
        -----
        To perform matrix-vector multiplication on batches of vectors,
        use `matvec`.

        For clarity, it is recommended to use the `matvec` or
        `matmat` methods directly instead of this method
        when interacting with dense vectors and matrices.

        r   rE   r   r   z6Dimension mismatch: array input `x` must have shape `(z,)` or a shape ending in `(z), K)` for some integer `K`. Given shape: N)r   rh   r   _ProductLinearOperatorr6   r   r   r   r   rJ   r5   r   r4   rK   r   )r7   r`   ru   vectorrj   r~   s         r+   r   zLinearOperator.dot9  s   ^ 	&&q)a()$dhh??^(qTXX>>A;'9!'< HH$$Q'

2A WW_FVVq[5QWWR[A%5FfLQC P../S 1$$%GG9. 
 !o%{{1~%{{1~% r,   c                 P    t        |      rt        d      | j                  |      S )zMatrix Multiplication.

        Used by the ``@`` operator.
        Rejects scalar input.
        Otherwise, equivalent to `dot`.
        0Scalar operands are not allowed, use '*' instead)r   r4   r   r   s     r+   
__matmul__zLinearOperator.__matmul__  s'     uOPP||E""r,   c                 P    t        |      rt        d      | j                  |      S )zMatrix Multiplication from the right.

        Used by the ``@`` operator from the right.
        Rejects scalar input.
        Otherwise, equivalent to `rdot`.
        r   )r   r4   __rmul__r   s     r+   __rmatmul__zLinearOperator.__rmatmul__  s'     uOPP}}U##r,   c                 $    | j                  |      S )zqMultiplication from the right.

        Used by the ``*`` operator from the right. Equivalent to `rdot`.
        )rdotr   s     r+   r   zLinearOperator.__rmul__  s    
 yy|r,   c                      j                  |       t        |t              rt        |  j                        S t        |      rt         | j                        S t        |      s&t        |      s j                  j                  |      } j                  d   }|j                  |fk(  }|j                  dk\  xr |j                  d   |k(  }|s#|s!d| d| d|j                   d}t        |       fd	}|r! j                  j                   ||            S |r' | j                  j                   ||                  S y
)a  Multi-purpose multiplication method from the right.

        .. note ::

            This method returns ``x A``.
            To perform adjoint multiplication instead, use one of
            `rmatvec` or `rmatmat`, or take the adjoint first,
            like ``self.H.rdot(x)`` or ``x * self.H``.

        Parameters
        ----------
        x : array_like or `LinearOperator` or scalar
            Array-like input will be interpreted as a 1-D row vector or
            2-D matrix (or batch of matrices)
            depending on its shape. See the Returns section for details.

        Returns
        -------
        xA : array or `LinearOperator`
            - For `LinearOperator` input, operator composition is performed.

            - For scalar input, a lazily scaled operator is returned.

            - Otherwise, the input is expected to take the form of a dense
              1-D vector or 2-D matrix (or batch of matrices),
              interpreted as follows
              (where ``self`` is an ``M`` by ``N`` linear operator):

              - If `x` has shape ``(M,)``
                it is interpreted as a row vector.
              - If `x` has shape ``(..., K, M)`` for some
                integer ``K``, it is interpreted as a matrix
                (or batch of matrices if there are batch dimensions).

        See Also
        --------
        dot : Multi-purpose multiplication method from the left.
        __rmul__ :
            Equivalent method, used by the ``*`` operator from the right.
        __rmatmul__ :
            Method used by the ``@`` operator from the right
            which rejects scalar input before calling this method.
        r   r   r   rE   z*Dimension mismatch: `x` must have shape `(z,)` or a shape ending in `(K, z&)` for some integer `K`. Given shape: .c                     | j                   xxdk(  r  | S xdk(  r  | S  dk(  r| j                  S 	 j                  j                  | dd      S )Nr   re   r   r   rE   )r   Tr6   moveaxis)r`   r7   s    r+   mTzLinearOperator.rdot.<locals>.mT  sO    ff     ss
#xx00B;;r,   N)r   rh   r   r   r6   r   r   r   r   rJ   r5   r   r4   r   rK   r   )r7   r`   rt   r   rj   r~   r   s   `      r+   r   zLinearOperator.rdot  s/   X 	&&q)a()!Tdhh??^(qTXX>>A;'9!'< HH$$Q'

2A WW_FVVq[5QWWR[A%5Ff@ D112 4$$%GG9A/ 
 !o%
< vv}}RU++$&&--1.// r,   c                 v    | j                  |       t        |      rt        | || j                        S t        S Nr   )r   r   _PowerLinearOperatorr6   NotImplemented)r7   ps     r+   __pow__zLinearOperator.__pow__  s0    &&q)q>'aDHH==!!r,   c                     | j                  |       t        |t              rt        | || j                        S t
        S )zLinear operator addition.

        The input must be a `LinearOperator`.
        A lazily summed linear operator is returned.
        r   )r   rh   r   _SumLinearOperatorr6   r   r   s     r+   __add__zLinearOperator.__add__  s5     	&&q)a(%dA$((;;!!r,   c                 2    t        | d| j                        S )NrE   r   )r   r6   r7   s    r+   __neg__zLinearOperator.__neg__  s    $T2$((;;r,   c                 &    | j                  |       S N)r   r   s     r+   __sub__zLinearOperator.__sub__  s    ||QBr,   c                     | j                   d}ndt        | j                         z   }dj                  d | j                  D              }d| d| j                  j
                   d| dS )	Nzunspecified dtypezdtype=r`   c              3   2   K   | ]  }t        |        y wr   )str).0dims     r+   	<genexpr>z*LinearOperator.__repr__.<locals>.<genexpr>  s     8cS8s   < z with >)r/   r   joinr5   r*   __name__)r7   dtr5   s      r+   __repr__zLinearOperator.__repr__  sa    ::$BC

O+B8TZZ885'4>>2236"Q??r,   c                 "    | j                         S )a  Hermitian adjoint.

        Returns the Hermitian adjoint of this linear operator,
        also known as the Hermitian
        conjugate or Hermitian transpose. For a complex matrix, the
        Hermitian adjoint is equal to the conjugate transpose.

        Returns
        -------
        `LinearOperator`
            Hermitian adjoint of self.

        See Also
        --------
        :attr:`~scipy.sparse.linalg.LinearOperator.H` : Equivalent attribute.
        )r   r   s    r+   ra   zLinearOperator.adjoint  s    " }}r,   c                 "    | j                         S )zHermitian adjoint.

        See Also
        --------
        scipy.sparse.linalg.LinearOperator.adjoint : Equivalent method.
        r   r   s    r+   r   zLinearOperator.H/  s     ||~r,   c                 "    | j                         S )zTranspose.

        Returns
        -------
        `LinearOperator`
            Transpose of the linear operator.

        See Also
        --------
        :attr:`~scipy.sparse.linalg.LinearOperator.T` : Equivalent attribute.
        )
_transposer   s    r+   	transposezLinearOperator.transpose9  s       r,   c                 "    | j                         S )zTranspose.

        See Also
        --------
        scipy.sparse.linalg.LinearOperator.transpose : Equivalent method.
        )r   r   s    r+   r   zLinearOperator.TG  s     ~~r,   c                 0    t        | | j                        S )ziDefault implementation of `_adjoint`.
        Defers to adjoint functions, e.g. `_rmatvec` for `_matvec`.r   )_AdjointLinearOperatorr6   r   s    r+   r   zLinearOperator._adjointQ  s     &dtxx88r,   c                 0    t        | | j                        S )z`Default implementation of `_transpose`.
        For `_matvec`, defers to `_rmatvec` + `np.conj`.r   )_TransposedLinearOperatorr6   r   s    r+   r   zLinearOperator._transposeV  s     )$((;;r,   r   )F)1r   
__module____qualname____doc____array_ufunc__classmethodtypesGenericAliasr   __annotations__intr   r9   r?   rC   rS   r"   r!   boolr   rK   r   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ra   propertyr   r   r   r   r   __classcell__r*   s   @r+   r   r   G   s   |~ O &11C1C%D{D
I(*
$,*
(81 1f&<4>%  6&448%E	!L&\	#	$T0l"
"< @&  !    9
<r,   c                   T     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 )Nrf   )r   r9   r'   "_CustomLinearOperator__matvec_impl#_CustomLinearOperator__rmatvec_impl#_CustomLinearOperator__rmatmat_impl"_CustomLinearOperator__matmat_implrS   )	r7   r5   rK   r   r   r/   r   r8   r*   s	           r+   r9   z_CustomLinearOperator.__init___  sI     	r*	#%%#r,   c                 \    | j                   | j                  |      S t        | 	  |      S r   )r   r   r"   r7   rZ   r*   s     r+   r"   z_CustomLinearOperator._matmatt  s/    )%%a((7?1%%r,   c                 $    | j                  |      S r   )r   r   s     r+   r!   z_CustomLinearOperator._matvecz  s    !!!$$r,   c                 V    | j                   }|t        d      | j                  |      S )Nzrmatvec is not defined)r   r   )r7   r`   funcs      r+   rk   z_CustomLinearOperator._rmatvec}  s/    ""<%&>??""1%%r,   c                 \    | j                   | j                  |      S t        | 	  |      S r   )r   r   r   r   s     r+   r   z_CustomLinearOperator._rmatmat  s0    *&&q))7#A&&r,   c           	          t        g | j                  d d | j                  d   | j                  d   | j                  | j                  | j                  | j
                  | j                  | j                        S )Nr   rE   )r5   rK   r   r   r   r/   r8   )r   r5   r   r   r   r   r/   r6   r   s    r+   r   z_CustomLinearOperator._adjoint  sm    $DDJJsODTZZ^DTZZ^D&&&&&&&&**xx
 	
r,   )NNNNN)r   r   r   r   r9   r"   r!   rk   r   r   r   r   s   @r+   r   r   \  s5    H *&%&'	
r,   r   c                   <     e Zd ZdZd fd	Zd Zd Zd Zd Z xZ	S )r   z$Adjoint of arbitrary Linear Operatorc                     g |j                   d d |j                   d   |j                   d   }t        | 	  |j                  ||       || _        |f| _        y Nr   rE   r5   r   r9   r/   Ar'   r7   r   r8   r5   r*   s       r+   r9   z_AdjointLinearOperator.__init__  V    9!''#2,99QWWR[9%,D	r,   c                 8    | j                   j                  |      S r   )r   rk   r   s     r+   r!   z_AdjointLinearOperator._matvec      vvq!!r,   c                 8    | j                   j                  |      S r   )r   r!   r   s     r+   rk   z_AdjointLinearOperator._rmatvec      vv~~a  r,   c                 8    | j                   j                  |      S r   )r   r   r   s     r+   r"   z_AdjointLinearOperator._matmat  r  r,   c                 8    | j                   j                  |      S r   )r   r"   r   s     r+   r   z_AdjointLinearOperator._rmatmat  r  r,   r   
r   r   r   r   r9   r!   rk   r"   r   r   r   s   @r+   r   r     s    ."!"!r,   r   c                   <     e Zd ZdZd fd	Zd Zd Zd Zd Z xZ	S )r   z*Transposition of arbitrary Linear Operatorc                     g |j                   d d |j                   d   |j                   d   }t        | 	  |j                  ||       || _        |f| _        y r   r   r   s       r+   r9   z"_TransposedLinearOperator.__init__  r  r,   c                     | j                   j                  | j                  j                  | j                   j                  |                  S r   )r6   conjr   rk   r   s     r+   r!   z!_TransposedLinearOperator._matvec  /    xx}}TVV__TXX]]1-=>??r,   c                     | j                   j                  | j                  j                  | j                   j                  |                  S r   )r6   r  r   r!   r   s     r+   rk   z"_TransposedLinearOperator._rmatvec  /    xx}}TVV^^DHHMM!,<=>>r,   c                     | j                   j                  | j                  j                  | j                   j                  |                  S r   )r6   r  r   r   r   s     r+   r"   z!_TransposedLinearOperator._matmat  r  r,   c                     | j                   j                  | j                  j                  | j                   j                  |                  S r   )r6   r  r   r"   r   s     r+   r   z"_TransposedLinearOperator._rmatmat  r  r,   r   r  r   s   @r+   r   r     s!    4@?@?r,   r   c                     |t         n|}|g }| D ]-  }|t        |d      s|j                  |j                         / t	        |d|iS )z;Returns the promoted dtype from input dtypes and operators.r/   r8   )r
   r   appendr/   r   )	operatorsdtypesr8   r)   s       r+   
_get_dtyper    sV    jbB~ %?wsG4MM#))$% 6)b))r,   c                   B     e Zd ZdZd fd	Zd Zd Zd Zd Zd Z	 xZ
S )	r   zRepresenting ``A + B``c                 Z   t        |t              rt        |t              st        d      |j                  ^ }}}|j                  ^ }}}	||f||	fk7  rt        d| d| d      t	        j
                  ||      }
||f| _        t        | !  t        ||g|      g |
|||       y )N)both operands have to be a LinearOperatorzcannot add  and : shape mismatchr   )
rh   r   r4   r5   rO   rr   r'   r   r9   r  r7   r   Br8   A_broadcast_dimsA_MA_NB_broadcast_dimsB_MB_Nr   r*   s              r+   r9   z_SumLinearOperator.__init__  s    !^,Jq.4QHII&'gg#	3&'gg#	3:#s#{1#U1#5EFGG//0@BRSF	QFr24Q6F4Q4QS4QSUVr,   c                 |    | j                   d   j                  |      | j                   d   j                  |      z   S Nr   re   r'   rK   r   s     r+   r!   z_SumLinearOperator._matvec  3    yy|""1%		!(;(;A(>>>r,   c                 |    | j                   d   j                  |      | j                   d   j                  |      z   S r%  r'   r   r   s     r+   rk   z_SumLinearOperator._rmatvec  3    yy|##A&1)=)=a)@@@r,   c                 |    | j                   d   j                  |      | j                   d   j                  |      z   S r%  r'   r   r   s     r+   r   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'   r   r7   r   r  s      r+   r   z_SumLinearOperator._adjoint  !    yy1ssQSSyr,   r   r   r   r   r   r9   r!   rk   r   r"   r   r   r   s   @r+   r   r     s'     	W?AA?r,   r   c                   B     e Zd ZdZd fd	Zd Zd Zd Zd Zd Z	 xZ
S )	r   zRepresenting ``A @ B``c                 R   t        |t              rt        |t              st        d      |j                  ^ }}}|j                  ^ }}}	||k7  rt        d| d| d      t	        j
                  ||      }
t        |   t        ||g|      g |
||	|       ||f| _	        y )Nr  zcannot multiply r  r  r   )
rh   r   r4   r5   ri   rr   r   r9   r  r'   r  s              r+   r9   z_ProductLinearOperator.__init__  s    !^,Jq.4QHII&'gg#	3&'gg#	3#:/s%s:JKLL../?AQRQFr24Q6F4Q4QS4QSUV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 Nre   r   r)  r   s     r+   rk   z_ProductLinearOperator._rmatvec  .    yy|##DIIaL$8$8$;<<r,   c                 v    | j                   d   j                  | j                   d   j                  |            S r9  r,  r   s     r+   r   z_ProductLinearOperator._rmatmat  r:  r,   c                 v    | j                   d   j                  | j                   d   j                  |            S r%  r.  r   s     r+   r"   z_ProductLinearOperator._matmat  r7  r,   c                 R    | j                   \  }}|j                  |j                  z  S r   r0  r1  s      r+   r   z_ProductLinearOperator._adjoint  r2  r,   r   r3  r   s   @r+   r   r     s$     	;==;r,   r   c                   B     e Zd ZdZd fd	Zd Zd Zd Zd Zd Z	 xZ
S )	r   zRepresenting ``alpha * A``c                 ,   t        |t              st        d      t        j                  |      st        d      t        |t
              r|j                  \  }}||z  }t        |g|g|      }t        | %  ||j                  |       ||f| _        y )NLinearOperator expected as Azscalar expected as alphar   )rh   r   r4   ri   isscalarr   r'   r  r   r9   r5   )r7   r   alphar8   alpha_originalr/   r*   s         r+   r9   z_ScaledLinearOperator.__init__  s    !^,;<<{{5!788a./ !A~ N*EA3B/,J	r,   c                 ^    | j                   d   | j                   d   j                  |      z  S r9  r&  r   s     r+   r!   z_ScaledLinearOperator._matvec  (    yy|diil11!444r,   c                 z    | j                   d   j                         | j                   d   j                  |      z  S r9  )r'   	conjugater   r   s     r+   rk   z_ScaledLinearOperator._rmatvec   1    yy|%%'$))A,*>*>q*AAAr,   c                 z    | j                   d   j                         | j                   d   j                  |      z  S r9  )r'   rG  r   r   s     r+   r   z_ScaledLinearOperator._rmatmat#  rH  r,   c                 ^    | j                   d   | j                   d   j                  |      z  S r9  r.  r   s     r+   r"   z_ScaledLinearOperator._matmat&  rE  r,   c                 Z    | j                   \  }}|j                  |j                         z  S r   )r'   r   rG  )r7   r   rB  s      r+   r   z_ScaledLinearOperator._adjoint)  s%    995ssU__&&&r,   r   r3  r   s   @r+   r   r   
  s&    $ 5BB5'r,   r   c                   H     e Zd ZdZd	 fd	Zd Zd Zd Zd Zd Z	d Z
 xZS )
r   zRepresenting ``A ** p``c                 0   t        |t              st        d      |j                  d   |j                  d   k7  rd|}t        |      t	        |      r|dk  rt        d      t
        |   t        |g|      |j                  |       ||f| _        y )Nr@  r   rE   z7square core-dimensions of LinearOperator expected, got r   z"non-negative integer expected as pr   )	rh   r   r4   r5   r   r   r9   r  r'   )r7   r   r   r8   r~   r*   s        r+   r9   z_PowerLinearOperator.__init__1  s    !^,;<<772;!''"+%KA5QCS/!|q1uABBQCB/"=F	r,   c                 f    t        |      }t        | j                  d         D ]
  } ||      } |S )Nre   )r   rX   r'   )r7   funr`   resr[   s        r+   _powerz_PowerLinearOperator._power=  s5    ajtyy|$ 	Ac(C	
r,   c                 T    | j                  | j                  d   j                  |      S Nr   )rQ  r'   rK   r   s     r+   r!   z_PowerLinearOperator._matvecC  !    {{499Q<..22r,   c                 T    | j                  | j                  d   j                  |      S rS  )rQ  r'   r   r   s     r+   rk   z_PowerLinearOperator._rmatvecF  !    {{499Q<//33r,   c                 T    | j                  | j                  d   j                  |      S rS  )rQ  r'   r   r   s     r+   r   z_PowerLinearOperator._rmatmatI  rV  r,   c                 T    | j                  | j                  d   j                  |      S rS  )rQ  r'   r   r   s     r+   r"   z_PowerLinearOperator._matmatL  rT  r,   c                 >    | j                   \  }}|j                  |z  S r   r0  )r7   r   r   s      r+   r   z_PowerLinearOperator._adjointO  s    yy1ssAvr,   r   )r   r   r   r   r9   rQ  r!   rk   r   r"   r   r   r   s   @r+   r   r   .  s)    !
3443r,   r   c                   0     e Zd ZdZd fd	Zd Zd Z xZS )MatrixLinearOperatorz8Operator defined by a matrix `A` which implements ``@``.c                 |    t         |   |j                  |j                  |       || _        d | _        |f| _        y r   )r   r9   r/   r5   r   _MatrixLinearOperator__adjr'   )r7   r   r8   r*   s      r+   r9   zMatrixLinearOperator.__init__W  s3    !''2.
D	r,   c                      | j                   |z  S r   )r   r   s     r+   r"   zMatrixLinearOperator._matmat]  s    vvzr,   c                 ~    | j                   &t        | j                  | j                        | _         | j                   S r   )r]  _AdjointMatrixOperatorr   r6   r   s    r+   r   zMatrixLinearOperator._adjoint`  s,    ::/488DDJzzr,   r   )r   r   r   r   r9   r"   r   r   r   s   @r+   r[  r[  T  s    Br,   r[  c                   *     e Zd ZdZd fd	Zd Z xZS )r`  z5Representing ``A.H``, for `MatrixLinearOperator` `A`.c                     |t         n|}|j                  dkD  r0t        |      rt        j                  |dd      }n|j
                  }n|j                  }t        | !  |j                  |      |       |f| _
        y )Nr   rE   r   r   )r
   r   r   r   swapaxesr   r   r   r9   r  r'   )r7   r   r8   A_Tr*   s       r+   r9   z_AdjointMatrixOperator.__init__i  sg    *Y"66A:{ooaR0dd##C"-D	r,   c                 J    t        | j                  d   | j                        S )Nr   r   )r[  r'   r6   r   s    r+   r   z_AdjointMatrixOperator._adjointu  s    #DIIaLTXX>>r,   r   )r   r   r   r   r9   r   r   r   s   @r+   r`  r`  f  s    ?
?r,   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   r9   )r7   r5   r/   r8   r*   s       r+   r9   zIdentityOperator.__init__z  s    r*r,   c                     |S r   rf   r   s     r+   r!   zIdentityOperator._matvec}      r,   c                     |S r   rf   r   s     r+   rk   zIdentityOperator._rmatvec  rj  r,   c                     |S r   rf   r   s     r+   r   zIdentityOperator._rmatmat  rj  r,   c                     |S r   rf   r   s     r+   r"   zIdentityOperator._matmat  rj  r,   c                     | S r   rf   r   s    r+   r   zIdentityOperator._adjoint  s    r,   NN)
r   r   r   r9   r!   rk   r   r"   r   r   r   s   @r+   rg  rg  y  s!    +r,   rg  c                    t        | t              r| S t        |       r\t        | t        j                        sBt        |       }t        |       rt        snt        j                  | d|      } t        | |      S t        |       rt        |       S t        | t        j                        r3t        j                  t        j                  |             } 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`.

    See the `LinearOperator` documentation for additional information.

    Parameters
    ----------
    A : object
        Object to convert to a `LinearOperator`. May be any one of the following types:

        - `numpy.ndarray`
        - `numpy.matrix`
        - `scipy.sparse` array
          (e.g. `~scipy.sparse.csr_array`, `~scipy.sparse.lil_array`, etc.)
        - `LinearOperator`
        - An object with ``.shape`` and ``.matvec`` attributes

    Returns
    -------
    B : LinearOperator
        A `LinearOperator` corresponding with `A`

    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   )r   r8   r   r5   rK   Nr   r   r/   )r   r   r/   ztype not understood)rh   r   r   ri   rj   r   r	   r   rO   
atleast_ndr[  r   
atleast_2drJ   r   r   r   r/   r5   rK   rM   )r   r8   r   r   r/   s        r+   r   r     s+   J !^$ :a#;Q!!$_qqR0A#A"--{#A&&!RYYMM"**Q-(#A&&q'wq(31i iiG1i iiG1gGGEGGQXXwu
 	
 )
**r,   ro  )+r   rn   r   r#   numpyri   scipyr   scipy._externalr   rO   scipy._lib._array_apir   r   r   r   r	   r
   r   r   r   r   scipy.sparser   scipy.sparse._sputilsr   r   r   r   __all__r   r   r   r   r  r   r   r   r   r[  r`  rg  r   rf   r,   r+   <module>rz     s   *X 
     2   " R R/
0 Q< Q< Q<h6
N 6
r!^ !,? ?,* >^ >!'N !'H#> #L> $?1 ?&~ ( F+ F+r,   