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)
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)
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
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
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
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))