Exemple #1
0
def draw(g: GT.Graph, color_mode=None, **kwargs):
    if color_mode is None:
        graph_draw(g)
    else:
        vc = None
        if color_mode == 'deg':
            vc = g.degree_property_map('total')
        graph_draw(g,
                   vertex_fill_color=vc,
                   vcmap=matplotlib.cm.gist_heat_r,
                   **kwargs)
Exemple #2
0
def split_gt(mesh, check_watertight=True, only_count=False):
    g = GTGraph()
    g.add_edge_list(mesh.face_adjacency())    
    component_labels = label_components(g, directed=False)[0].a
    if check_watertight: 
        degree = g.degree_property_map('total').a
    meshes     = deque()
    components = group(component_labels)
    if only_count: return len(components)

    for i, current in enumerate(components):
        fill_holes = False
        if check_watertight:
            degree_3 = degree[current] == 3
            degree_2 = degree[current] == 2
            if not degree_3.all():
                if np.logical_or(degree_3, degree_2).all():
                    fill_holes = True
                else: 
                    continue

        # these faces have the original vertex indices
        faces_original = mesh.faces[current]
        face_normals   = mesh.face_normals[current]
        # we find the unique vertex indices, so we can reindex from zero
        unique_vert    = np.unique(faces_original)
        vertices       = mesh.vertices[unique_vert]
        replacement    = np.zeros(unique_vert.max()+1, dtype=np.int)
        replacement[unique_vert] = np.arange(len(unique_vert))
        faces                    = replacement[faces_original]
        new_mesh = mesh.__class__(faces        = faces, 
                                  face_normals = face_normals, 
                                  vertices     = vertices)
        new_meta = deepcopy(mesh.metadata)
        if 'name' in new_meta:
            new_meta['name'] = new_meta['name'] + '_' + str(i)
        new_mesh.metadata.update(new_meta)
        if fill_holes: 
            try:              new_mesh.fill_holes(raise_watertight=True)
            except MeshError: continue
        meshes.append(new_mesh)
    return list(meshes)
Exemple #3
0
def is_watertight_gt(mesh):
    g = GTGraph()
    g.add_edge_list(mesh.face_adjacency())    
    degree     = g.degree_property_map('total').a
    watertight = np.equal(degree, 3).all()
    return watertight
Exemple #4
0
def budgeted_heuristic_querying(g: graph_tool.Graph, y, weights=None, budget=50, compute_hulls_between_queries=False,
                          hull_as_optimization=False, use_adjacency=False):
    '''

    :param g:
    :param paths: list of paths
    :param y: ground truth
    :param weight:
    :return:
    '''

    deg = g.degree_property_map("total").a
    #deg = deg*deg
    if use_adjacency:
        dist_map = graph_tool.topology.shortest_distance(g, weights=weights).get_2d_array(range(g.num_vertices())).T

        adjacency = dist_map.copy()
        adjacency[adjacency > 1] = 0
    else:
        # to prevent overflow etc.
        dist_map = graph_tool.topology.shortest_distance(g, weights=weights).get_2d_array(
            range(g.num_vertices())).T.astype(np.double)
        dist_map[dist_map > g.num_vertices()] = np.inf

    # hack to allow both endpoints as candidates:
    # new_spc = paths.copy()
    # for p in paths:
    #    new_spc.append(p[::-1])

    # paths = new_spc

    comps, hist = graph_tool.topology.label_components(g)
    n = g.num_vertices()
    classes = np.unique(y)
    known_labels = -np.ones(g.num_vertices()) * np.inf

    candidate_hulls = np.zeros(n, dtype=np.object)
    candidate_hull_sizes = np.zeros(n)
    known_classes = dict()
    classes_hulls = dict()
    for j in range(n):
        candidate_hulls[j] = dict()

    for c in classes:
        known_classes[c] = set()
        classes_hulls[c] = dict()
        classes_hulls[c] = np.zeros(n, np.bool)
        for j in range(n):
            one_hot = np.zeros(n, dtype=np.bool)
            one_hot[j] = True
            candidate_hulls[j][c] = one_hot  # singleton hull
    for z in range(budget):
        # compute most promising vertex
        for p in range(n):
            if known_labels[p] == -np.inf:
                candidate_hull_sizes[p] = helper_sum_sizes(candidate_hulls[p], classes_hulls)
            else:
                candidate_hull_sizes[p] = -1

        maximizers = np.where(candidate_hull_sizes == np.max(candidate_hull_sizes))[0]


        #overlap of classes
        classes_hulls_overlap = np.sum(np.array([key_index_array[1] for key_index_array in classes_hulls.items()]), axis=0)
        #classes_hulls_overlap[classes_hulls_overlap<=1] = 0
        maximizers = maximizers[np.where(classes_hulls_overlap[maximizers] == np.min(classes_hulls_overlap[maximizers]))[0]]

        #maximizers = maximizers[np.where(deg[maximizers] == np.max(deg[maximizers]))[0]]

        p_star = np.random.choice(maximizers)

        # query it
        known_labels[p_star] = y[p_star]

        # update data structures
        known_classes[known_labels[p_star]].add(p_star)
        classes_hulls[known_labels[p_star]] = candidate_hulls[p_star][known_labels[p_star]]

        for j in range(n):

            if known_labels[j] == -np.inf:# and not classes_hulls[c][j]:
                # if not candidate_hulls[j][c][candidate]:
                # if not classes_hulls[c][path[candidates[j]]]:
                # classes_hulls_c_set = set(np.where(classes_hulls[c])[0])
                # old_hull_with_new_candidate = list(classes_hulls_c_set)
                # old_hull_with_new_candidate.append(path[candidates[j]])
                c = known_labels[p_star]
                candidate_hulls[j][c] = compute_hull(g, list(known_classes[c].union([j])), weights,
                                                        dist_map, comps, hist,
                                                         hull_as_optimization)  # , classes_hulls_c_set)


                test = np.zeros(n, dtype=np.bool)

                for p1 in list(known_classes[c].union([j])):
                    for p2 in list(known_classes[c].union([j])):
                        test[dist_map[p1,:]+ dist_map[:,p2] == dist_map[p1,p2]] = True



        '''if compute_hulls_between_queries:
            for c in classes:
                known_labels[np.where(compute_hull(g, np.where(known_labels == c)[0], weights, dist_map, comps, hist))[0]] = c'''

        if compute_hulls_between_queries:
            known_labels_augmented = known_labels.copy()
            known_classes_hulls_temp = np.zeros((n, len(classes)), dtype=np.bool)
            for i, c in enumerate(classes):
                known_classes_hulls_temp[:, i] = compute_hull(g, np.where(known_labels_augmented == c)[0], weights,
                                                              dist_map, comps, hist, compute_closure=False)

            for i, c in enumerate(classes):
                only_c = known_classes_hulls_temp[:, i] & ~(
                    np.sum(known_classes_hulls_temp[:, np.arange(len(classes)) != i], axis=1).astype(bool))
                known_labels_augmented[only_c] = c

        else:
            known_labels_augmented = known_labels

        if use_adjacency:
            prediction = label_propagation(adjacency, known_labels_augmented, y, use_adjacency=use_adjacency)
        else:
            prediction = label_propagation(dist_map, known_labels_augmented, y, use_adjacency=use_adjacency)
        print("=====")
        print(z + 1, np.sum(known_labels > -np.inf))
        print(np.sum(np.array([i[1] for i in list(classes_hulls.items())]),axis=1))
        print("accuracy", np.sum(prediction == y) / y.size)
        #print(known_classes)

    return known_labels
Exemple #5
0
def budgeted_spc_querying(g : graph_tool.Graph, paths, y, weights=None, budget=50,  compute_hulls_between_queries=False, hull_as_optimization=False, use_adjacency=False):
    '''

    :param g:
    :param paths: list of paths
    :param y: ground truth
    :param weight:
    :return:
    '''

    if use_adjacency:
        dist_map = graph_tool.topology.shortest_distance(g, weights=weights).get_2d_array(range(g.num_vertices())).T

        adjacency = dist_map.copy()
        adjacency[adjacency > 1] = 0
    else:
        #to prevent overflow etc.
        dist_map = graph_tool.topology.shortest_distance(g, weights=weights).get_2d_array(
            range(g.num_vertices())).T.astype(np.double)
        dist_map[dist_map > g.num_vertices()] = np.inf

    #hack to allow both endpoints as candidates:
    #new_spc = paths.copy()
    #for p in paths:
    #    new_spc.append(p[::-1])

    #paths = new_spc

    comps, hist = graph_tool.topology.label_components(g)
    n = g.num_vertices()
    classes = np.unique(y)
    known_labels = -np.ones(g.num_vertices())*np.inf

    candidates = np.zeros(len(paths), dtype=np.int)
    candidate_generators = np.zeros(len(paths), dtype=np.object)
    for i, path in enumerate(paths):
        candidate_generators[i] = binarySearchGenerator(known_labels, path, 0, len(path)-1)
        candidates[i] = next(candidate_generators[i])

    candidate_hulls = np.zeros(len(paths), dtype=np.object)
    candidate_hull_sizes = np.zeros(len(paths))
    classes_hull_sizes = np.zeros(len(paths))
    known_classes = dict()
    classes_hulls = dict()

    deg = g.degree_property_map("total").a
    deg = deg*deg

    for j, candidate in enumerate(candidates):
        candidate_hulls[j] = dict()

    for c in classes:
        known_classes[c] = set()
        classes_hulls[c] = dict()
        for j, candidate in enumerate(candidates):
            temp = np.zeros(n, dtype=np.bool)
            classes_hulls[c] = temp.copy() #empty hulls
            temp[paths[j][candidate]] = True
            candidate_hulls[j][c] = temp #singleton hull
    for z in range(budget):
        #compute most promising vertex
        for p in range(len(paths)):
            if known_labels[paths[p][candidates[p]]] == -np.inf:
                candidate_hull_sizes[p] = helper_sum_sizes(candidate_hulls[p], classes_hulls)
            else:
                candidate_hull_sizes[p] = -1

        maximizers = np.where(candidate_hull_sizes == np.max(candidate_hull_sizes))[0]

        #prefer not queried paths
        if np.any(candidates[maximizers] == 0):
            maximizers = maximizers[np.where(candidates[maximizers] == 0)[0]]
            p_star = np.random.choice(maximizers)
        else:
            p_star = np.random.choice(maximizers)
        candidate = paths[p_star][candidates[p_star]]

        #query it
        known_labels[candidate] = y[candidate]

        #update data structures
        known_classes[known_labels[candidate]].add(candidate)
        classes_hulls[known_labels[candidate]] = candidate_hulls[p_star][known_labels[candidate]]



        for j in range(len(candidates)):
            path = paths[j]
            while known_labels[path[candidates[j]]] != -np.inf or path[candidates[j]] in classes_hulls[known_labels[candidate]]:
                try:
                    candidates[j] = next(candidate_generators[j])
                except StopIteration:
                    break
            #if not candidate_hulls[j][c][candidate]:
            #if not classes_hulls[c][path[candidates[j]]]:
                #classes_hulls_c_set = set(np.where(classes_hulls[c])[0])
                #old_hull_with_new_candidate = list(classes_hulls_c_set)
                #old_hull_with_new_candidate.append(path[candidates[j]])
            for c in classes:
                candidate_hulls[j][c] = compute_hull(g, list(known_classes[c].union([path[candidates[j]]])), weights, dist_map, comps, hist, hull_as_optimization)#, classes_hulls_c_set)

        '''if compute_hulls_between_queries:
            for c in classes:
                known_labels[np.where(compute_hull(g, np.where(known_labels == c)[0], weights, dist_map, comps, hist))[0]] = c'''

        if compute_hulls_between_queries:
            known_labels_augmented = known_labels.copy()
            known_classes_hulls_temp = np.zeros((n, len(classes)), dtype=np.bool)
            for i, c in enumerate(classes):
                known_classes_hulls_temp[:,i] = compute_hull(g, np.where(known_labels_augmented == c)[0], weights, dist_map, comps, hist, compute_closure=False)

            for i, c in enumerate(classes):
                only_c = known_classes_hulls_temp[:,i] & ~(np.sum(known_classes_hulls_temp[:,np.arange(len(classes))!=i],axis=1).astype(bool))
                known_labels_augmented[only_c] = c

        else:
            known_labels_augmented = known_labels

        if use_adjacency:
            prediction = label_propagation(adjacency, known_labels_augmented, y, use_adjacency=use_adjacency)
        else:
            prediction = label_propagation(dist_map, known_labels_augmented, y, use_adjacency=use_adjacency)
        print("======")
        print(z+1, np.sum(known_labels>-np.inf))
        print("accuracy", np.sum(prediction==y)/y.size)
        #print(known_classes)
        
    return known_labels
def gen_fs(dicProperties):
	np.random.seed()
	graphFS = Graph()
	# on définit la fraction des arcs à utiliser la réciprocité
	f = dicProperties["Reciprocity"]
	rFracRecip =  f/(2.0-f)
	# on définit toutes les grandeurs de base
	rInDeg = dicProperties["InDeg"]
	rOutDeg = dicProperties["OutDeg"]
	nNodes = 0
	nEdges = 0
	rDens = 0.0
	if "Nodes" in dicProperties.keys():
		nNodes = dicProperties["Nodes"]
		graphFS.add_vertex(nNodes)
		if "Edges" in dicProperties.keys():
			nEdges = dicProperties["Edges"]
			rDens = nEdges / float(nNodes**2)
			dicProperties["Density"] = rDens
		else:
			rDens = dicProperties["Density"]
			nEdges = int(np.floor(rDens*nNodes**2))
			dicProperties["Edges"] = nEdges
	else:
		nEdges = dicProperties["Edges"]
		rDens = dicProperties["Density"]
		nNodes = int(np.floor(np.sqrt(nEdges/rDens)))
		graphFS.add_vertex(nNodes)
		dicProperties["Nodes"] = nNodes
	# on définit le nombre d'arcs à créer
	nArcs = int(np.floor(rDens*nNodes**2)/(1+rFracRecip))
	# on définit les paramètres fonctions de probabilité associées F(x) = A x^{-tau}
	Ai = nArcs*(rInDeg-1)/(nNodes)
	Ao = nArcs*(rOutDeg-1)/(nNodes)
	# on définit les moyennes des distributions de pareto 2 = lomax
	rMi = 1/(rInDeg-2.)
	rMo = 1/(rOutDeg-2.)
	# on définit les trois listes contenant les degrés sortant/entrant/bidirectionnels associés aux noeuds i in range(nNodes)
	lstInDeg = np.random.pareto(rInDeg,nNodes)+1
	lstOutDeg = np.random.pareto(rOutDeg,nNodes)+1
	lstInDeg = np.floor(np.multiply(Ai/np.mean(lstInDeg), lstInDeg)).astype(int)
	lstOutDeg = np.floor(np.multiply(Ao/np.mean(lstOutDeg), lstOutDeg)).astype(int)
	# on génère les stubs qui vont être nécessaires et on les compte
	nInStubs = int(np.sum(lstInDeg))
	nOutStubs = int(np.sum(lstOutDeg))
	lstInStubs = np.zeros(np.sum(lstInDeg))
	lstOutStubs = np.zeros(np.sum(lstOutDeg))
	nStartIn = 0
	nStartOut = 0
	for vert in range(nNodes):
		nInDegVert = lstInDeg[vert]
		nOutDegVert = lstOutDeg[vert]
		for j in range(np.max([nInDegVert,nOutDegVert])):
			if j < nInDegVert:
				lstInStubs[nStartIn+j] += vert
			if j < nOutDegVert:
				lstOutStubs[nStartOut+j] += vert
		nStartOut+=nOutDegVert
		nStartIn+=nInDegVert
	# on vérifie qu'on a à peu près le nombre voulu d'edges
	while nInStubs*(1+rFracRecip)/float(nArcs) < 0.95 :
		vert = np.random.randint(0,nNodes)
		nAddInStubs = int(np.floor(Ai/rMi*(np.random.pareto(rInDeg)+1)))
		lstInStubs = np.append(lstInStubs,np.repeat(vert,nAddInStubs)).astype(int)
		nInStubs+=nAddInStubs
	while nOutStubs*(1+rFracRecip)/float(nArcs) < 0.95 :
		nAddOutStubs = int(np.floor(Ao/rMo*(np.random.pareto(rOutDeg)+1)))
		lstOutStubs = np.append(lstOutStubs,np.repeat(vert,nAddOutStubs)).astype(int)
		nOutStubs+=nAddOutStubs
	# on s'assure d'avoir le même nombre de in et out stubs (1.13 is an experimental correction)
	nMaxStubs = int(1.13*(2.0*nArcs)/(2*(1+rFracRecip)))
	if nInStubs > nMaxStubs and nOutStubs > nMaxStubs:
		np.random.shuffle(lstInStubs)
		np.random.shuffle(lstOutStubs)
		lstOutStubs.resize(nMaxStubs)
		lstInStubs.resize(nMaxStubs)
		nOutStubs = nInStubs = nMaxStubs
	elif nInStubs < nOutStubs:
		np.random.shuffle(lstOutStubs)
		lstOutStubs.resize(nInStubs)
		nOutStubs = nInStubs
	else:
		np.random.shuffle(lstInStubs)
		lstInStubs.resize(nOutStubs)
		nInStubs = nOutStubs
	# on crée le graphe, les noeuds et les stubs
	nRecip = int(np.floor(nInStubs*rFracRecip))
	nEdges = nInStubs + nRecip +1
	# les stubs réciproques
	np.random.shuffle(lstInStubs)
	np.random.shuffle(lstOutStubs)
	lstInRecip = lstInStubs[0:nRecip]
	lstOutRecip = lstOutStubs[0:nRecip]
	lstEdges = np.array([np.concatenate((lstOutStubs,lstInRecip)),np.concatenate((lstInStubs,lstOutRecip))]).astype(int)
	# add edges
	graphFS.add_edge_list(np.transpose(lstEdges))
	remove_self_loops(graphFS)
	remove_parallel_edges(graphFS)
	lstIsolatedVert = find_vertex(graphFS, graphFS.degree_property_map("total"), 0)
	graphFS.remove_vertex(lstIsolatedVert)
	graphFS.reindex_edges()
	nNodes = graphFS.num_vertices()
	nEdges = graphFS.num_edges()
	rDens = nEdges / float(nNodes**2)
	# generate types
	rInhibFrac = dicProperties["InhibFrac"]
	lstTypesGen = np.random.uniform(0,1,nEdges)
	lstTypeLimit = np.full(nEdges,rInhibFrac)
	lstIsExcitatory = np.greater(lstTypesGen,lstTypeLimit)
	nExc = np.count_nonzero(lstIsExcitatory)
	epropType = graphFS.new_edge_property("int",np.multiply(2,lstIsExcitatory)-np.repeat(1,nEdges)) # excitatory (True) or inhibitory (False)
	graphFS.edge_properties["type"] = epropType
	# and weights
	if dicProperties["Weighted"]:
		lstWeights = dicGenWeights[dicProperties["Distribution"]](graphFS,dicProperties,nEdges,nExc) # generate the weights
		epropW = graphFS.new_edge_property("double",lstWeights) # crée la propriété pour stocker les poids
		graphFS.edge_properties["weight"] = epropW
	return graphFS
Exemple #7
0
    if g.edge(v, u) is None:
        g.add_edge(v, u)

# In[31]:

weight = g.new_edge_property('float')
weight.set_value(EPS)

# In[32]:

for i, r in tqdm(df.iterrows(), total=df.shape[0]):
    u, v, w = int(r['u']), int(r['v']), r['w']
    weight[g.edge(u, v)] = w
g.edge_properties['weights'] = weight

# In[33]:

deg_out = g.degree_property_map('out', weight=weight)

# In[34]:

r = deg_out.a
r = r[r < 2]
s = pd.Series(r)
# s.hist(bins=30)

# In[35]:

g.save('data/{}/graph.gt'.format(graph))
g.save('data/{}/graph_weighted.gt'.format(graph))