(x, AggOp, A, T, thresh=1.0, **kwargs)
Eliminate canidates locally.

    Helper function that determines where to eliminate candidates locally
    on a per aggregate basis.

    Parameters
    ----------
    x : array
        n x 1 vector of new candidate
    AggOp : CSR or CSC sparse matrix
        Aggregation operator for the level that x was generated for
    A : sparse matrix
        Operator for the level that x was generated for
    T : sparse matrix
        Tentative prolongation operator for the level that x was generated for
    thresh : scalar
        Constant threshold parameter to decide when to drop candidates

    Returns
    -------
    Nothing, x is modified in place
Eliminate canidates locally.
Eliminate canidates locally .
def eliminate_local_candidates(x, AggOp, A, T, thresh=1.0, **kwargs):
    """Eliminate canidates locally.

    Helper function that determines where to eliminate candidates locally
    on a per aggregate basis.

    Parameters
    ----------
    x : array
        n x 1 vector of new candidate
    AggOp : CSR or CSC sparse matrix
        Aggregation operator for the level that x was generated for
    A : sparse matrix
        Operator for the level that x was generated for
    T : sparse matrix
        Tentative prolongation operator for the level that x was generated for
    thresh : scalar
        Constant threshold parameter to decide when to drop candidates

    Returns
    -------
    Nothing, x is modified in place

    """
    if not (isspmatrix_csr(AggOp) or isspmatrix_csc(AggOp)):
        raise TypeError('AggOp must be a CSR or CSC matrix')

    if kwargs:  # process any needed kwargs for elimination
        pass

    AggOp = AggOp.tocsc()
    ndof = max(x.shape)
    npde = int(ndof/AggOp.shape[0])

    def aggregate_wise_inner_product(z, AggOp, npde, ndof):
        """Inner products per aggregate.

        Helper function that calculates <z, z>_i, i.e., the
        inner product of z only over aggregate i
        Returns a vector of length num_aggregates where entry i is <z, z>_i

        """
        z = np.ravel(z)*np.ravel(z)
        innerp = np.zeros((1, AggOp.shape[1]), dtype=z.dtype)
        for j in range(npde):
            innerp += z[slice(j, ndof, npde)].reshape(1, -1) * AggOp

        return innerp.reshape(-1, 1)

    def get_aggregate_weights(AggOp, A, z, npde, ndof):
        """Weights per aggregate.

        Calculate local aggregate quantities
        Return a vector of length num_aggregates where entry i is
        (card(agg_i)/A.shape[0]) ( <Az, z>/rho(A) )

        """
        _ = ndof
        rho = approximate_spectral_radius(A)
        zAz = np.dot(z.reshape(1, -1), A*z.reshape(-1, 1))
        card = npde * (AggOp.indptr[1:]-AggOp.indptr[:-1])
        weights = (np.ravel(card)*zAz)/(A.shape[0]*rho)
        return weights.reshape(-1, 1)

    # Run test 1, which finds where x is small relative to its energy
    weights = thresh * get_aggregate_weights(AggOp, A, x, npde, ndof)
    mask1 = aggregate_wise_inner_product(x, AggOp, npde, ndof) <= weights

    # Run test 2, which finds where x is already approximated
    # accurately by the existing T
    projected_x = x - T*(T.T*x)
    mask2 = aggregate_wise_inner_product(projected_x,
                                         AggOp, npde, ndof) <= weights

    # Combine masks and zero out corresponding aggregates in x
    mask = np.ravel(mask1 + mask2).nonzero()[0]
    if mask.shape[0] > 0:
        mask = npde * AggOp[:, mask].indices
        for j in range(npde):
            x[mask+j] = 0.0
def eliminate_local_candidates ( x , AggOp , A , T , thresh = 1.0 , * * kwargs ) : if not ( isspmatrix_csr ( AggOp ) or isspmatrix_csc ( AggOp ) ) : raise TypeError ( 'AggOp must be a CSR or CSC matrix' ) if kwargs : # process any needed kwargs for elimination pass AggOp = AggOp . tocsc ( ) ndof = max ( x . shape ) npde = int ( ndof / AggOp . shape [ 0 ] ) def aggregate_wise_inner_product ( z , AggOp , npde , ndof ) : """Inner products per aggregate.

        Helper function that calculates <z, z>_i, i.e., the
        inner product of z only over aggregate i
        Returns a vector of length num_aggregates where entry i is <z, z>_i

        """ z = np . ravel ( z ) * np . ravel ( z ) innerp = np . zeros ( ( 1 , AggOp . shape [ 1 ] ) , dtype = z . dtype ) for j in range ( npde ) : innerp += z [ slice ( j , ndof , npde ) ] . reshape ( 1 , - 1 ) * AggOp return innerp . reshape ( - 1 , 1 ) def get_aggregate_weights ( AggOp , A , z , npde , ndof ) : """Weights per aggregate.

        Calculate local aggregate quantities
        Return a vector of length num_aggregates where entry i is
        (card(agg_i)/A.shape[0]) ( <Az, z>/rho(A) )

        """ _ = ndof rho = approximate_spectral_radius ( A ) zAz = np . dot ( z . reshape ( 1 , - 1 ) , A * z . reshape ( - 1 , 1 ) ) card = npde * ( AggOp . indptr [ 1 : ] - AggOp . indptr [ : - 1 ] ) weights = ( np . ravel ( card ) * zAz ) / ( A . shape [ 0 ] * rho ) return weights . reshape ( - 1 , 1 ) # Run test 1, which finds where x is small relative to its energy weights = thresh * get_aggregate_weights ( AggOp , A , x , npde , ndof ) mask1 = aggregate_wise_inner_product ( x , AggOp , npde , ndof ) <= weights # Run test 2, which finds where x is already approximated # accurately by the existing T projected_x = x - T * ( T . T * x ) mask2 = aggregate_wise_inner_product ( projected_x , AggOp , npde , ndof ) <= weights # Combine masks and zero out corresponding aggregates in x mask = np . ravel ( mask1 + mask2 ) . nonzero ( ) [ 0 ] if mask . shape [ 0 ] > 0 : mask = npde * AggOp [ : , mask ] . indices for j in range ( npde ) : x [ mask + j ] = 0.0