o
    Ebc<                     @   s   d Z ddlZddlmZ dgZd!ddZd	d
 Zedd Zedd Z	dd Z
dd Zdd Zdd Zd"ddZdd Zdd Zdd Zdd  ZdS )#zSparse block 1-norm estimator.
    N)aslinearoperator
onenormest      Fc                 C   s  t | } | jd | jd krtd| jd }||krhtt | t|}|j||fkr9tddt|j t	|j
dd}|j|fkrQtddt|j t|}t||}	|dd|f }
|| }nt| | j||\}}	}
}}|sy|r|f}|r||	f7 }|r||
f7 }|S |S )a	  
    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.

    Examples
    --------
    >>> from scipy.sparse import csc_matrix
    >>> from scipy.sparse.linalg import onenormest
    >>> A = csc_matrix([[1., 0., 0.], [5., 8., 2.], [0., -1., 0.]], dtype=float)
    >>> A.toarray()
    array([[ 1.,  0.,  0.],
           [ 5.,  8.,  2.],
           [ 0., -1.,  0.]])
    >>> onenormest(A)
    9.0
    >>> np.linalg.norm(A.toarray(), ord=1)
    9.0
    r      z1expected the operator to act like a square matrixzinternal error: zunexpected shape ZaxisN)r   shape
ValueErrornpasarraymatmatidentity	Exceptionstrabssumargmaxelementary_vector_onenormest_coreH)AtitmaxZ	compute_vZ	compute_wnZ
A_explicitZcol_abs_sumsZargmax_jvwestnmults
nresamplesresult r    A/usr/lib/python3/dist-packages/scipy/sparse/linalg/_onenormest.pyr      s8   I





c                    s   d  fdd}|S )z
    Decorator for an elementwise function, to apply it blockwise along
    first dimension, to avoid excessive memory usage in temporaries.
       c                    s   | j d  k r| S | d   }tj| j d f|j dd   |jd}||d  < ~t | j d  D ]}| ||   |||  < q6|S )Nr   r   dtype)r   r
   zerosr$   range)xZy0yj
block_sizefuncr    r!   wrapper   s   &"z%_blocked_elementwise.<locals>.wrapperr    )r,   r-   r    r*   r!   _blocked_elementwisex   s   r.   c                 C   s&   |   }d||dk< |t| }|S )a9  
    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."

    r   r   )copyr
   r   XYr    r    r!   sign_round_up   s   r3   c                 C   s   t jt | ddS )Nr   r   )r
   maxr   )r1   r    r    r!   _max_abs_axis1   s   r5   c                 C   sZ   d}d }t d| jd |D ]}tjt| |||  dd}|d u r&|}q||7 }q|S )Nr"   r   r   )r&   r   r
   r   r   )r1   r+   rr)   r(   r    r    r!   _sum_abs_axis0   s    
r7   c                 C   s   t j| td}d||< |S )Nr#   r   )r
   r%   float)r   ir   r    r    r!   r      s   r   c                 C   s8   | j dks| j|jkrtd| jd }t| ||kS )Nr   z2expected conformant vectors with entries in {-1,1}r   )ndimr   r	   r
   dot)r   r   r   r    r    r!   vectors_are_parallel   s   
r<   c                    s.   | j D ] t fdd|j D s dS qdS )Nc                 3       | ]}t  |V  qd S Nr<   .0r   r   r    r!   	<genexpr>       z;every_col_of_X_is_parallel_to_a_col_of_Y.<locals>.<genexpr>FT)Tanyr0   r    rB   r!   (every_col_of_X_is_parallel_to_a_col_of_Y   s
   
rG   c                    sb    j \}} d d | f t fddt| D rdS |d ur/tfdd|jD r/dS dS )Nc                 3   s&    | ]}t  d d |f V  qd S r>   r?   )rA   r)   r1   r   r    r!   rC      s   $ z*column_needs_resampling.<locals>.<genexpr>Tc                 3   r=   r>   r?   r@   rB   r    r!   rC      rD   F)r   rF   r&   rE   )r9   r1   r2   r   r   r    rH   r!   column_needs_resampling   s   
rI   c                 C   s0   t jjdd|jd dd d |d d | f< d S )Nr   r   sizer   )r
   randomrandintr   )r9   r1   r    r    r!   resample_column   s   0rN   c                 C   s   t | |p	| |k S r>   )r
   Zallclose)abr    r    r!   less_than_or_close   s   rQ   c                 C   s  t | }t |}|jd }t||f}|dkr1tjjdd||d fdd d |ddddf< |t| }d}d}d}	t|}
	 t|	|}t
|}t|}|  |ddd }t|}t|	|}t|}|	dkrtt|t|dd|f |dd|f r	 ||
fS t|ddd d| }
||
 }t|D ]}t||
| |dd|f< q|	dkrt|d |d stdt|d |d std|	d	krt|D ]}t|| || std
q|}|}|	d7 }	qB)a"  
    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.

    r   r   r   rJ   NTzinvariant (2.2) is violated   zinvariant (2.3) is violated)r   r   r
   onesrL   rM   r8   r&   r   r   r7   r   sortr3   r5   rQ   r4   r;   argsortr   r   )r   ATr   A_linear_operatorAT_linear_operatorr   r1   Zg_prevZh_prevkindr2   gbest_jSZhr)   r    r    r!   _algorithm_2_2   sT   '
2

.ra   c                 C   s
  t | }t |}|dk rtd|dk rtd| jd }||kr%tdd}d}tj||ftd}	|dkr]td|D ]}
t|
|	 q;t|D ]}
t|
|	r\t|
|	 |d7 }t|
|	sNqG|	t| }	tj	dtj
d}d}tj	||ftd}d}d}	 t||	}|d7 }t|}t|}t|}||ks|dkr|dkr|| }|dd|f }|dkr||kr|}n|}|}||krnt|}~t||rn|dkrt|D ]}
t|
||rt|
| |d7 }t|
||sq~t||}|d7 }t|}~|dkrt||| krnlt|ddd
 d|t|   }~|dkrGt|d| | r5nDt||}t||  || f}t|D ]}t||| |	dd|f< qK|d| t|d| |  }t||f}|d7 }q{t||}|||||fS )a  
    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.

    r   z$at least two iterations are requiredr   zat least one column is requiredr   z't should be smaller than the order of Ar#   NTrR   )r   r	   r   r
   rT   r8   r&   rN   rI   r%   Zintpr   r   r7   r4   r   r3   rG   r5   rV   lenr/   Zin1dallZconcatenater   )r   rW   r   r   rX   rY   r   r   r   r1   r9   Zind_histZest_oldr^   rZ   r[   r2   Zmagsr   r]   Zind_bestr   ZS_oldr_   r`   seenr)   Znew_indr   r    r    r!   r   C  s   )







(
"
>r   )r   r   FFr>   )__doc__Znumpyr
   Zscipy.sparse.linalgr   __all__r   r.   r3   r5   r7   r   r<   rG   rI   rN   rQ   ra   r   r    r    r    r!   <module>   s&    
m



g