ó
Ê½÷Xc           @` sÛ   d  Z  d d l m Z m Z m Z d d l Z d d l m Z d g Z	 d d e
 e
 d „ Z d	 „  Z e d
 „  ƒ Z e d „  ƒ Z d „  Z d „  Z d „  Z d „  Z d d „ Z d „  Z d „  Z d „  Z d „  Z d S(   s   Sparse block 1-norm estimator.
i    (   t   divisiont   print_functiont   absolute_importN(   t   aslinearoperatort
   onenormesti   i   c         C` s§  t  |  ƒ }  |  j d |  j d k r5 t d ƒ ‚ n  |  j d } | | k r3t j t  |  ƒ j t j | ƒ ƒ ƒ } | j | | f k r© t d d t | j ƒ ƒ ‚ n  t	 | ƒ j
 d d ƒ } | j | f k rò t d d t | j ƒ ƒ ‚ n  t j | ƒ } t | | ƒ }	 | d d … | f }
 | | } n' t |  |  j | | ƒ \ } }	 }
 } } | sf| rŸ| f } | r…| |	 f 7} n  | r›| |
 f 7} n  | S| Sd S(   s!  
    Compute a lower bound of the 1-norm of a sparse matrix.

    Parameters
    ----------
    A : ndarray or other linear operator
        A linear operator that can be transposed and that can
        produce matrix products.
    t : int, optional
        A positive parameter controlling the tradeoff between
        accuracy versus time and memory usage.
        Larger values take longer and use more memory
        but give more accurate output.
    itmax : int, optional
        Use at most this many iterations.
    compute_v : bool, optional
        Request a norm-maximizing linear operator input vector if True.
    compute_w : bool, optional
        Request a norm-maximizing linear operator output vector if True.

    Returns
    -------
    est : float
        An underestimate of the 1-norm of the sparse matrix.
    v : ndarray, optional
        The vector such that ||Av||_1 == est*||v||_1.
        It can be thought of as an input to the linear operator
        that gives an output with particularly large norm.
    w : ndarray, optional
        The vector Av which has relatively large 1-norm.
        It can be thought of as an output of the linear operator
        that is relatively large in norm compared to the input.

    Notes
    -----
    This is algorithm 2.4 of [1].

    In [2] it is described as follows.
    "This algorithm typically requires the evaluation of
    about 4t matrix-vector products and almost invariably
    produces a norm estimate (which is, in fact, a lower
    bound on the norm) correct to within a factor 3."

    .. versionadded:: 0.13.0

    References
    ----------
    .. [1] Nicholas J. Higham and Francoise Tisseur (2000),
           "A Block Algorithm for Matrix 1-Norm Estimation,
           with an Application to 1-Norm Pseudospectra."
           SIAM J. Matrix Anal. Appl. Vol. 21, No. 4, pp. 1185-1201.

    .. [2] Awad H. Al-Mohy and Nicholas J. Higham (2009),
           "A new scaling and squaring algorithm for the matrix exponential."
           SIAM J. Matrix Anal. Appl. Vol. 31, No. 3, pp. 970-989.

    i    i   s1   expected the operator to act like a square matrixs   internal error: s   unexpected shape t   axisN(   R   t   shapet
   ValueErrort   npt   asarrayt   matmatt   identityt	   Exceptiont   strt   abst   sumt   argmaxt   elementary_vectort   _onenormest_coret   H(   t   At   tt   itmaxt	   compute_vt	   compute_wt   nt
   A_explicitt   col_abs_sumst   argmax_jt   vt   wt   estt   nmultst
   nresamplest   result(    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyR      s4    <''	c         ` s   d ‰  ‡  ‡ f d †  } | S(   s‘   
    Decorator for an elementwise function, to apply it blockwise along
    first dimension, to avoid excessive memory usage in temporaries.
    i   i   c         ` sµ   |  j  d ˆ  k  r ˆ |  ƒ Sˆ |  ˆ   ƒ } t j |  j  d f | j  d d | j ƒ} | | ˆ  *~ xC t ˆ  |  j  d ˆ  ƒ D]( } ˆ |  | | ˆ  !ƒ | | | ˆ  +q W| Sd  S(   Ni    i   t   dtype(   R   R   t   zerosR#   t   range(   t   xt   y0t   yt   j(   t
   block_sizet   func(    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   wrappert   s    
-
 &i   (    (   R+   R,   (    (   R*   R+   s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   _blocked_elementwisem   s    c         C` s3   |  j  ƒ  } d | | d k <| t j | ƒ } | S(   s9  
    This should do the right thing for both real and complex matrices.

    From Higham and Tisseur:
    "Everything in this section remains valid for complex matrices
    provided that sign(A) is redefined as the matrix (aij / |aij|)
    (and sign(0) = 1) transposes are replaced by conjugate transposes."

    i   i    (   t   copyR   R   (   t   Xt   Y(    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   sign_round_up‚   s    c         C` s   t  j t  j |  ƒ d d ƒS(   NR   i   (   R   t   maxR   (   R/   (    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   _max_abs_axis1“   s    c         C` s|   d } d  } xi t d |  j d | ƒ D]N } t j t j |  | | | !ƒ d d ƒ} | d  k rj | } q& | | 7} q& W| S(   Ni   i   i    R   i   (   t   NoneR%   R   R   R   R   (   R/   R*   t   rR)   R(   (    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   _sum_abs_axis0˜   s     )	c         C` s#   t  j |  d t ƒ} d | | <| S(   NR#   i   (   R   R$   t   float(   R   t   iR   (    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyR   ¤   s    
c         C` sS   |  j  d k s! |  j | j k r0 t d ƒ ‚ n  |  j d } t j |  | ƒ | k S(   Ni   s2   expected conformant vectors with entries in {-1,1}i    (   t   ndimR   R   R   t   dot(   R   R   R   (    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   vectors_are_parallelª   s    !c         ` s;   x4 |  j  D]) ‰  t ‡  f d †  | j  Dƒ ƒ s
 t Sq
 Wt S(   Nc         3` s   |  ] } t  ˆ  | ƒ Vq d  S(   N(   R;   (   t   .0R   (   R   (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pys	   <genexpr>¶   s    (   t   Tt   anyt   Falset   True(   R/   R0   (    (   R   s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt(   every_col_of_X_is_parallel_to_a_col_of_Y´   s    c         ` s„   ˆ  j  \ } } ˆ  d  d  … |  f ‰ t ‡  ‡ f d †  t |  ƒ Dƒ ƒ rN t S| d  k	 r€ t ‡ f d †  | j Dƒ ƒ r€ t Sn  t S(   Nc         3` s.   |  ]$ } t  ˆ ˆ  d  d  … | f ƒ Vq d  S(   N(   R;   (   R<   R)   (   R/   R   (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pys	   <genexpr>Á   s    c         3` s   |  ] } t  ˆ  | ƒ Vq d  S(   N(   R;   (   R<   R   (   R   (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pys	   <genexpr>Ä   s    (   R   R>   R%   R@   R4   R=   R?   (   R8   R/   R0   R   R   (    (   R/   R   s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   column_needs_resampling»   s    %c         C` s>   t  j j d d d | j d ƒd d | d  d  … |  f <d  S(   Ni    i   t   sizei   (   R   t   randomt   randintR   (   R8   R/   (    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   resample_columnÉ   s    c         C` s   t  j |  | ƒ p |  | k  S(   N(   R   t   allclose(   t   at   b(    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   less_than_or_closeÍ   s    c         C` sÆ  t  |  ƒ } t  | ƒ } | j d } t j | | f ƒ } | d k rŒ t j j d d d | | d f ƒd d | d d … d d … f <n  | t | ƒ } d } d } d }	 t | ƒ }
 xÿt	 r»t j
 | j | ƒ ƒ } t | ƒ } t j | ƒ } | j ƒ  | d d d … } t | ƒ } t j
 | j | ƒ ƒ } t | ƒ } |	 d k r—t t | ƒ t j | d d … | f | d d … | f ƒ ƒ r—Pq—n  t j | ƒ d d d … |  }
 | |
 } x7 t | ƒ D]) } t | |
 | ƒ | d d … | f <qÎW|	 d k rVt | d | d ƒ s-t d ƒ ‚ n  t | d | d ƒ sVt d ƒ ‚ qVn  |	 d k r¢x= t | ƒ D], } t | | | | ƒ sot d	 ƒ ‚ qoqoWn  | } | } |	 d 7}	 q½ W| |
 f S(
   s#  
    This is Algorithm 2.2.

    Parameters
    ----------
    A : ndarray or other linear operator
        A linear operator that can produce matrix products.
    AT : ndarray or other linear operator
        The transpose of A.
    t : int, optional
        A positive parameter controlling the tradeoff between
        accuracy versus time and memory usage.

    Returns
    -------
    g : sequence
        A non-negative decreasing vector
        such that g[j] is a lower bound for the 1-norm
        of the column of A of jth largest 1-norm.
        The first entry of this vector is therefore a lower bound
        on the 1-norm of the linear operator A.
        This sequence has length t.
    ind : sequence
        The ith entry of ind is the index of the column A whose 1-norm
        is given by g[i].
        This sequence of indices has length t, and its entries are
        chosen from range(n), possibly with repetition,
        where n is the order of the operator A.

    Notes
    -----
    This algorithm is mainly for testing.
    It uses the 'ind' array in a way that is similar to
    its usage in algorithm 2.4.  This algorithm 2.2 may be easier to test,
    so it gives a chance of uncovering bugs related to indexing
    which could have propagated less noticeably to algorithm 2.4.

    i    i   i   RC   Niÿÿÿÿs   invariant (2.2) is violatedi   s   invariant (2.3) is violated(   R   R   R   t   onesRD   RE   R7   R4   R%   R@   R	   R
   R6   R   t   sortR1   R3   RJ   R2   R:   t   argsortR   R   (   R   t   ATR   t   A_linear_operatort   AT_linear_operatorR   R/   t   g_prevt   h_prevt   kt   indR0   t   gt   best_jt   St   Zt   hR)   (    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   _algorithm_2_2Ñ   sP    'F	

A 
'c         C` sK  t  |  ƒ } t  | ƒ } | d k  r3 t d ƒ ‚ n  | d k  rN t d ƒ ‚ n  |  j d } | | k rv t d ƒ ‚ n  d } d } t j | | f d t ƒ}	 | d k rx$ t d | ƒ D] }
 t |
 |	 ƒ q¹ WxD t | ƒ D]3 }
 x* t |
 |	 ƒ rt |
 |	 ƒ | d 7} qæ WqÝ Wn  |	 t | ƒ }	 t j	 d d t j
 ƒ} d } t j	 | | f d t ƒ} d } d } xºt r(t j | j |	 ƒ ƒ } | d 7} t | ƒ } t j | ƒ } t j | ƒ } | | k sÙ| d k r| d k rò| | } n  | d d … | f } n  | d k r-| | k r-| } Pn  | } | } | | k rIPn  t | ƒ } ~ t | | ƒ rkPn  | d k rÁxG t | ƒ D]6 }
 x- t |
 | | ƒ r¹t |
 | ƒ | d 7} qWq„Wn  ~ t j | j | ƒ ƒ } | d 7} t | ƒ } ~ | d k rt | ƒ | | k rPn  t j | ƒ d d d	 … | t | ƒ  j ƒ  } ~ | d k r­t j | |  | ƒ j ƒ  rzPn  t j | | ƒ } t j | | | | f ƒ } n  x7 t | ƒ D]) } t | | | ƒ |	 d d … | f <qºW| |  t j | |  | ƒ } t j | | f ƒ } | d 7} qoWt | | ƒ } | | | | | f S(
   sð  
    Compute a lower bound of the 1-norm of a sparse matrix.

    Parameters
    ----------
    A : ndarray or other linear operator
        A linear operator that can produce matrix products.
    AT : ndarray or other linear operator
        The transpose of A.
    t : int, optional
        A positive parameter controlling the tradeoff between
        accuracy versus time and memory usage.
    itmax : int, optional
        Use at most this many iterations.

    Returns
    -------
    est : float
        An underestimate of the 1-norm of the sparse matrix.
    v : ndarray, optional
        The vector such that ||Av||_1 == est*||v||_1.
        It can be thought of as an input to the linear operator
        that gives an output with particularly large norm.
    w : ndarray, optional
        The vector Av which has relatively large 1-norm.
        It can be thought of as an output of the linear operator
        that is relatively large in norm compared to the input.
    nmults : int, optional
        The number of matrix products that were computed.
    nresamples : int, optional
        The number of times a parallel column was observed,
        necessitating a re-randomization of the column.

    Notes
    -----
    This is algorithm 2.4.

    i   s$   at least two iterations are requiredi   s   at least one column is requiredi    s'   t should be smaller than the order of AR#   Niÿÿÿÿ(   R   R   R   R   RK   R7   R%   RF   RB   R$   t   intpR4   R@   R	   R
   R6   R2   R   R1   RA   R3   RM   t   lenR.   t   in1dt   allt   concatenateR   (   R   RN   R   R   RO   RP   R   R    R!   R/   R8   t   ind_histt   est_oldRW   RS   RT   R0   t   magsR   RV   t   ind_bestR   t   S_oldRX   RY   t   seenR)   t   new_indR   (    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyR   8  s    )	

"0!'(   t   __doc__t
   __future__R    R   R   t   numpyR   t   scipy.sparse.linalgR   t   __all__R?   R   R-   R1   R3   R6   R   R;   RA   R4   RB   RF   RJ   RZ   R   (    (    (    s>   /tmp/pip-build-7oUkmx/scipy/scipy/sparse/linalg/_onenormest.pyt   <module>   s"   	`				
				g