예제 #1
0
def heat_diffusion_ind(graph, taus=TAUS, order=ORDER, proc=PROC):
    '''
    This method computes the heat diffusion waves for each of the nodes
    INPUT:
    -----------------------
    graph    :    Graph (etworkx)
    taus     :    list of scales for the wavelets. The higher the tau,
                  the better the spread of the heat over the graph
    order    :    order of the polynomial approximation
    proc     :    which procedure to compute the signatures (approximate == that
                  is, with Chebychev approx -- or exact)

    OUTPUT:
    -----------------------
    heat     :     tensor of length  len(tau) x n_nodes x n_nodes
                   where heat[tau,:,u] is the wavelet for node u
                   at scale tau
    taus     :     the associated scales
    '''
    # Compute Laplacian
    a = nx.adjacency_matrix(graph)
    n_nodes, _ = a.shape
    #thres = np.vectorize(lambda x : x if x > 1e-4 * 1.0 / n_nodes else 0)
    lap = laplacian(a)
    print('n_nodes:', n_nodes)
    print('laplacian nnz(GB):', "%.3f" % (lap.nnz / 1024 / 1024 / 1024 * 4))
    n_filters = len(taus)
    if proc == 'exact':
        ### Compute the exact signature
        lamb, U = np.linalg.eigh(lap.todense())
        heat = {}
        for i in range(n_filters):
            heat[i] = U.dot(np.diagflat(np.exp(-taus[i] *
                                               lamb).flatten())).dot(U.T)
    else:
        # Create a constant matrix
        sparse_eye = sc.sparse.eye(n_nodes)
        heat = {
            i: sc.sparse.csc_matrix((n_nodes, n_nodes))
            for i in range(n_filters)
        }
        monome = {0: sparse_eye, 1: lap - sparse_eye}
        for k in range(2, order + 1):
            monome[k] = 2 * (lap - sparse_eye).dot(monome[k - 1]) - monome[k -
                                                                           2]
            print("Computing monome", k)
            print("monome number of nonzero(GB):",
                  "%.3f" % (monome[k].nnz / 1024 / 1024 / 1024 * 4))
        for i in range(n_filters):
            coeffs = compute_cheb_coeff_basis(taus[i], order)
            heat[i] = sc.sum(
                [coeffs[k] * monome[k] for k in range(0, order + 1)])
            #temp = thres(heat[i].A) # cleans up the small coefficients
            temp = heat[i]
            temp.data = np.where(temp.data > 1e-4 * 1.0 / n_nodes, temp.data,
                                 0)
            heat[i] = sc.sparse.csc_matrix(temp)
            print("Computing heat map for filter", i)
    return heat, taus
예제 #2
0
def graphwave_alg(graph,
                  time_pnts,
                  taus='auto',
                  verbose=False,
                  approximate_lambda=True,
                  order=ORDER,
                  proc=PROC,
                  nb_filters=NB_FILTERS,
                  **kwargs):
    ''' wrapper function for computing the structural signatures using GraphWave
    INPUT
    --------------------------------------------------------------------------------------
    graph             :   nx Graph
    time_pnts         :   time points at which to evaluate the characteristic function
    taus              :   list of scales that we are interested in. Alternatively,
                          'auto' for the automatic version of GraphWave
    verbose           :   the algorithm prints some of the hidden parameters
                          as it goes along
    approximate_lambda:   (boolean) should the range oflambda be approximated or
                          computed?
    proc              :   which procedure to compute the signatures (approximate == that
                          is, with Chebychev approx -- or exact)
    nb_filters        :   nuber of taus that we require if  taus=='auto'
    OUTPUT
    --------------------------------------------------------------------------------------
    chi               :  embedding of the function in Euclidean space
    heat_print        :  returns the actual embeddings of the nodes
    taus              :  returns the list of scales used.
    '''
    if taus == 'auto':
        if approximate_lambda is not True:
            a = nx.adjacency_matrix(graph)
            lap = laplacian(a)
            try:
                l1 = np.sort(
                    sc.sparse.linalg.eigsh(lap,
                                           2,
                                           which='SM',
                                           return_eigenvectors=False))[1]
            except:
                l1 = np.sort(
                    sc.sparse.linalg.eigsh(lap,
                                           5,
                                           which='SM',
                                           return_eigenvectors=False))[1]
        else:
            l1 = 1.0 / graph.number_of_nodes()
        smax = -np.log(ETA_MIN) * np.sqrt(0.5 / l1)
        smin = -np.log(ETA_MAX) * np.sqrt(0.5 / l1)
        taus = np.linspace(smin, smax, nb_filters)
        print(taus)
    heat_print, _ = heat_diffusion_ind(graph,
                                       list(taus),
                                       order=order,
                                       proc=proc)
    chi = charac_function_multiscale(heat_print, time_pnts)
    return chi, heat_print, taus
예제 #3
0
def heat_diffusion_ind(graph, taus=TAUS, order = ORDER, proc = PROC):
    '''
    This method computes the heat diffusion waves for each of the nodes
    INPUT:
    -----------------------
    graph    :    Graph, can be of type networkx or pygsp
    taus     :    list of 4 scales for the wavelets. The higher the tau,
                  the better the spread
    order    :    order of the polynomial approximation

    OUTPUT:
    -----------------------
    heat     :     tensor of length  len(tau) x n_nodes x n_nodes
                   where heat[tau,:,u] is the wavelet for node u
                   at scale tau
    '''
    # Compute Laplacian
    a = nx.adjacency_matrix(graph)
    n_nodes, _ = a.shape
    thres = np.vectorize(lambda x : x if x > 1e-4 * 1.0 / n_nodes else 0)
    lap = laplacian(a)
    n_filters = len(taus)
    if proc == 'exact':
        ### Compute the exact signature
        lamb, U = np.linalg.eigh(lap.todense())
        heat = {}
        for i in range(n_filters):
             heat[i] = U.dot(np.diagflat(np.exp(- taus[i] * lamb).flatten())).dot(U.T)
    else:
        heat = {i: sc.sparse.csc_matrix((n_nodes, n_nodes)) for i in range(n_filters) }
        monome = {0: sc.sparse.eye(n_nodes), 1: lap - sc.sparse.eye(n_nodes)}
        for k in range(2, order + 1):
             monome[k] = 2 * (lap - sc.sparse.eye(n_nodes)).dot(monome[k-1]) - monome[k - 2]
        for i in range(n_filters):
            coeffs = compute_cheb_coeff_basis(taus[i], order)
            heat[i] = sc.sum([ coeffs[k] * monome[k] for k in range(0, order + 1)])
            temp = thres(heat[i].A) # cleans up the small coefficients
            heat[i] = sc.sparse.csc_matrix(temp)
    return heat, taus