def _monomial_index(self, multi_index): """ Return the sign and the index of the monomial in the basis. """ degree = len(multi_index) multi_index = list(multi_index) sign = selection_sort(multi_index) multi_index = tuple(multi_index) if multi_index in self._basis[degree]: return sign, self._basis[degree].index(tuple(multi_index)) else: return 1, None
def undirected_graph_has_odd_automorphism(g): n = len(g) edges = g.edges() G = Graph([list(range(n)), edges]) for sigma in G.automorphism_group().gens( ): # NOTE: it suffices to check generators edge_permutation = [ tuple(sorted([sigma(edge[0]), sigma(edge[1])])) for edge in edges ] index_permutation = [edges.index(e) for e in edge_permutation] if selection_sort(index_permutation) == -1: return True return False
def _derivative_on_basis(self, degree, i, j): """ Return the index and the sign of the derivative of the ``i``th monomial of degree ``degree`` in the basis, with respect to the ``j``th odd coordinate. """ monomial = self._basis[degree][i] if not j in monomial: return None, 1 lst = list(monomial) sign = 1 if lst.index(j) % 2 == 0 else -1 lst.remove(j) # remove first instance sign *= selection_sort(lst) derivative = tuple(lst) assert derivative in self._basis[degree-1] return self._basis[degree-1].index(derivative), sign
def undirected_graph_canonicalize(g): n = len(g) edges = g.edges() G, sigma = Graph([list(range(n)), edges]).canonical_label(certificate=True) new_edges = list(G.edges(labels=False)) edge_permutation = [ tuple(sorted([sigma[edge[0]], sigma[edge[1]]])) for edge in edges ] index_permutation = [new_edges.index(e) for e in edge_permutation] undo_canonicalize = [0] * n for k, v in sigma.items(): undo_canonicalize[v] = k return UndirectedGraph( n, list(new_edges)), undo_canonicalize, selection_sort(index_permutation)
def undirected_to_directed_graph_coefficient(undirected_graph, directed_graph): g = Graph(undirected_graph.edges()) h = Graph(directed_graph.edges()) are_isomorphic, sigma = g.is_isomorphic(h, certificate=True) assert are_isomorphic edges = directed_graph.edges() edge_permutation = [ edges.index((sigma[a], sigma[b])) if (sigma[a], sigma[b]) in edges else edges.index((sigma[b], sigma[a])) for (a, b) in undirected_graph.edges() ] sign = selection_sort(edge_permutation) multiplicity = len(g.automorphism_group()) // len( DiGraph(directed_graph.edges()).automorphism_group()) return sign * multiplicity
def _mul_on_basis(self, degree1, k1, degree2, k2): """ Return the index and the sign of the monomial that results from multiplying the ``k1``th monomial of degree ``degree1`` by the ``k2``th monomial of degree ``degree2``. """ if degree1 + degree2 > self.__ngens: return None, 1 left = self._basis[degree1][k1] right = self._basis[degree2][k2] lst = list(left+right) sign = selection_sort(lst) # detect repetitions in sorted list for i in range(0, len(lst)-1): if lst[i] == lst[i+1]: return None, 1 prod = tuple(lst) assert prod in self._basis[degree1+degree2] return self._basis[degree1+degree2].index(prod), sign
def formality_graph_has_odd_automorphism(g): n = len(g) edges = g.edges() partition = [[v] for v in range(g.num_ground_vertices())] + [ list( range(g.num_ground_vertices(), g.num_ground_vertices() + g.num_aerial_vertices())) ] G = DiGraph([list(range(n)), edges]) for sigma in G.automorphism_group(partition=partition).gens( ): # NOTE: it suffices to check generators edge_permutation = [ tuple([sigma(edge[0]), sigma(edge[1])]) for edge in edges ] index_permutation = [edges.index(e) for e in edge_permutation] if selection_sort(index_permutation) == -1: return True return False
def formality_graph_canonicalize(g): n = len(g) edges = g.edges() partition = [[v] for v in range(g.num_ground_vertices())] + [ list( range(g.num_ground_vertices(), g.num_ground_vertices() + g.num_aerial_vertices())) ] H = DiGraph([list(range(n)), edges]) if len(H.edges()) != len(g.edges()): raise ValueError( "don't know how to canonicalize graph with double edges") G, sigma = H.canonical_label(partition=partition, certificate=True) new_edges = list(G.edges(labels=False)) edge_permutation = [ tuple([sigma[edge[0]], sigma[edge[1]]]) for edge in edges ] index_permutation = [new_edges.index(e) for e in edge_permutation] undo_canonicalize = [0] * n for k, v in sigma.items(): undo_canonicalize[v] = k return FormalityGraph( g.num_ground_vertices(), g.num_aerial_vertices(), list(new_edges)), undo_canonicalize, selection_sort(index_permutation)
def canonicalize_edges(self): """ Lexicographically order the edges of this graph and return the sign of that edge permutation. """ return selection_sort(self._edges)