示例#1
0
    def test_trivial_searches(self):
        from sage.all import Subsets
        for begin in [
                ('level=10&weight=1-20&dim=1',
                    ['Results (displaying all 21 matches)', '171901114', 'No', '10.723', 'A-L signs']
                    ),
                ('level=10%2C13%2C17&weight=1-8&dim=1',
                    ['Results (displaying all 12 matches)', '1373', 'No', '0.136']
                    )]:
            for s in Subsets(['has_self_twist=no', 'is_self_dual=yes', 'nf_label=1.1.1.1','char_order=1','inner_twist_count=1']):
                s = '&'.join(['/ModularForm/GL2/Q/holomorphic/?search_type=List', begin[0]] + list(s))
                page = self.tc.get(s,  follow_redirects=True)
                for elt in begin[1]:
                    assert elt in page.data, s

        for begin in [
                ('level=1-330&weight=1&projective_image=D2',
                    ['Results (displaying all 49 matches)',
                        '328.1.c.a', r"\sqrt{-82}", r"\sqrt{-323}", r"\sqrt{109}"]
                    ),
                ('level=900-1000&weight=1-&projective_image=D2',
                    ['Results (displaying all 26 matches)', r"\sqrt{-1}", r"\sqrt{-995}", r"\sqrt{137}"]
                    )]:
            for s in Subsets(['has_self_twist=yes', 'has_self_twist=cm', 'has_self_twist=rm',  'projective_image_type=Dn','dim=1-4']):
                s = '&'.join(['/ModularForm/GL2/Q/holomorphic/?search_type=List', begin[0]] + list(s))
                page = self.tc.get(s,  follow_redirects=True)
                for elt in begin[1]:
                    assert elt in page.data, s
示例#2
0
    def padically_evaluate_regular(self, datum):
        T = datum.toric_datum
        if not T.is_regular():
            raise ValueError('Can only processed regular toric data')

        M = Set(range(T.length()))
        q = SR.var('q')

        alpha = {}

        for I in Subsets(M):
            F = [T.initials[i] for i in I]
            V = SubvarietyOfTorus(F, torus_dim=T.ambient_dim)
            alpha[I] = V.count()

        def cat(u, v):
            return vector(list(u) + list(v))

        for I in Subsets(M):
            cnt = sum((-1)**len(J) * alpha[I + J] for J in Subsets(M - I))
            if not cnt:
                continue

            P = DirectProductOfPolyhedra(T.polyhedron,
                                         StrictlyPositiveOrthant(len(I)))

            it = iter(identity_matrix(ZZ, len(I)).rows())
            ieqs = []
            for i in M:
                ieqs.append(
                    cat(
                        vector(ZZ, (0, )),
                        cat(
                            vector(ZZ, T.initials[i].exponents()[0]) -
                            vector(ZZ, T.lhs[i].exponents()[0]),
                            next(it) if i in I else zero_vector(ZZ, len(I)))))

            if not ieqs:
                ieqs = [vector(ZZ, (T.ambient_dim + len(I) + 1) * [0])]

            Q = Polyhedron(ieqs=ieqs,
                           base_ring=QQ,
                           ambient_dim=T.ambient_dim + len(I))

            foo, ring = symbolic_to_ratfun(
                cnt * (q - 1)**len(I) / q**(T.ambient_dim),
                [var('t'), var('q')])
            corr_cnt = CyclotomicRationalFunction.from_laurent_polynomial(
                foo, ring)

            Phi = matrix([
                cat(T.integrand[0], zero_vector(ZZ, len(I))),
                cat(T.integrand[1], vector(ZZ,
                                           len(I) * [-1]))
            ]).transpose()
            sm = RationalSet([P.intersection(Q)]).generating_function()
            for z in sm.monomial_substitution(QQ['t', 'q'], Phi):
                yield corr_cnt * z
示例#3
0
    def topologically_evaluate_regular(self, datum):
        if not datum.is_regular():
            raise ValueError('need a regular datum')

        euler_cap = {}
        torus_factor_dim = {}

        N = Set(range(len(datum.polynomials)))

        _, d, _ = split_off_torus([datum.initials[i].num for i in N])
        min_dim = datum.ambient_dim - d

        # NOTE: triangulation/"topologisation" of RationalSet instances only
        # considers cones of maximal dimension.
        if datum.RS.dim() <= min_dim - 2:
            return
            yield

        if datum.RS.dim() >= min_dim:
            raise RuntimeError('this should be impossible')

        for I in Subsets(N):
            F = [datum.initials[i].num for i in I]
            V = SubvarietyOfTorus(F, torus_dim=datum.ambient_dim)
            U,W = V.split_off_torus()
            torus_factor_dim[I] = W.torus_dim

            assert torus_factor_dim[I] >= min_dim

            if W.torus_dim > min_dim:
                continue
            euler_cap[I] = U.khovanskii_characteristic() if U.is_nondegenerate() else U.euler_characteristic()

        for I in Subsets(N):
            chi = sum((-1)**len(J) * euler_cap[I + J] for J in Subsets(N - I)
                      if torus_factor_dim[I + J] == min_dim)
            if not chi:
                continue

            I = list(I)
            id = identity_matrix(ZZ, len(I))
            def vectorise(first, k, vec):
                w = id[I.index(k)] if k in I else vector(ZZ,len(I))
                return vector(ZZ, [first] + list(vec) + list(w))

            polytopes = []
            for (i, j) in self.pairs:
                vertices = [vectorise(0, k, datum.ideals[i].initials[m].exponents()[0]) for m, k in enumerate(datum._ideal2poly[i])] +\
                           [vectorise(1, k, datum.ideals[j].initials[m].exponents()[0]) for m, k in enumerate(datum._ideal2poly[j])]
                polytopes.append(Polyhedron(vertices=vertices, ambient_dim=1+datum.ambient_dim + len(I)))
            extended_RS = (RationalSet(StrictlyPositiveOrthant(1)) * datum.RS *
                           RationalSet(StrictlyPositiveOrthant(len(I))))

            for surf in topologically_evaluate_monomial_integral(extended_RS, polytopes,
                                                                 self.integrand, dims=[min_dim+len(I)]):
                yield SURF(scalar=chi*surf.scalar, rays=surf.rays)
示例#4
0
    def topologically_evaluate_regular(self, datum):
        if not datum.is_regular():
            raise ValueError('need a regular datum')

        euler_cap = {}
        torus_factor_dim = {}

        N = Set(range(len(datum.polynomials)))
        _, d, _ = split_off_torus([datum.initials[i].num for i in N])
        min_dim = datum.ambient_dim - d

        if datum.RS.dim() < min_dim:
            logger.debug('Totally irrelevant datum')
            return
            yield

        for I in Subsets(N):
            F = [datum.initials[i].num for i in I]
            V = SubvarietyOfTorus(F, torus_dim=datum.ambient_dim)
            U,W = V.split_off_torus()
            torus_factor_dim[I] = W.torus_dim
            euler_cap[I] = U.khovanskii_characteristic() if U.is_nondegenerate() else U.euler_characteristic()
            assert torus_factor_dim[I] >= min_dim

        for I in Subsets(N):
            chi = sum((-1)**len(J) * euler_cap[I+J] for J in Subsets(N-I) if torus_factor_dim[I+J] == min_dim)
            if not chi:
                logger.debug('Vanishing Euler characteristic: I = %s' % I)
                continue

            I = list(I)
            polytopes = []

            id = identity_matrix(ZZ, len(I))
            def vectorise(k, vec):
                w = id[I.index(k)] if k in I else vector(ZZ,len(I))
                return vector(ZZ, list(vec) + list(w))

            assert len(datum._ideal2poly[0]) == len(datum.ideals[0].gens)
            polytopes = [Polyhedron(vertices=[vectorise(k, datum.ideals[0].initials[m].exponents()[0]) for m,k in enumerate(datum._ideal2poly[0])],
                                    ambient_dim=datum.ambient_dim+len(I))]

            extended_RS = datum.RS * RationalSet(StrictlyPositiveOrthant(len(I)))

            assert all(extended_RS.ambient_dim == P.ambient_dim() for P in polytopes)
            for surf in topologically_evaluate_monomial_integral(extended_RS, polytopes,
                                                                 [ (1,), (0,) ],
                                                                 dims=[min_dim + len(I)],
                                                                 ):
                yield SURF(scalar=chi*surf.scalar, rays=surf.rays)
示例#5
0
    def padically_evaluate_regular(self, datum, extra_RS=None):
        if not datum.is_regular():
            raise ValueError('need a regular datum')

        # The extra variable's valuation is in extra_RS.
        if extra_RS is None:
            extra_RS = RationalSet(StrictlyPositiveOrthant(1))

        q = var('q')
        count_cap = {}
        N = Set(range(len(datum.polynomials)))

        for I in Subsets(N):
            F = [datum.initials[i].num for i in I]
            V = SubvarietyOfTorus(F, torus_dim=datum.ambient_dim)
            count_cap[I] = V.count()

            # BEGIN SANITY CHECK
            # q = var('q')
            # u, w = V.split_off_torus()
            # assert ((count_cap[I]/(q-1)**w.torus_dim).simplify_full())(q=1) == u.euler_characteristic()
            # END SANITY CHECK

        for I in Subsets(N):
            cnt = sum((-1)**len(J) * count_cap[I + J] for J in Subsets(N - I))
            if not cnt:
                continue

            I = list(I)
            id = identity_matrix(ZZ, len(I))

            def vectorise(first, k, vec):
                w = id[I.index(k)] if k in I else vector(ZZ, len(I))
                return vector(ZZ, [first] + list(vec) + list(w))

            polytopes = []
            for (i, j) in self.pairs:
                vertices = [vectorise(0, k, datum.ideals[i].initials[m].exponents()[0]) for m, k in enumerate(datum._ideal2poly[i])] +\
                           [vectorise(1, k, datum.ideals[j].initials[m].exponents()[0]) for m, k in enumerate(datum._ideal2poly[j])]
                polytopes.append(Polyhedron(vertices=vertices, ambient_dim=1 + datum.ambient_dim + len(I)))

            extended_RS = extra_RS * datum.RS * RationalSet(StrictlyPositiveOrthant(len(I)))

            foo, ring = symbolic_to_ratfun(cnt * (q - 1)**(1 + len(I)) / q**(1 + datum.ambient_dim), [var('t'), var('q')])
            corr_cnt = CyclotomicRationalFunction.from_laurent_polynomial(foo, ring)

            for z in padically_evaluate_monomial_integral(extended_RS, polytopes, self.integrand):
                yield corr_cnt * z
示例#6
0
def zero_forcing_set_bruteforce(graph, bound=None):
    """
   Return a zero forcing set of minimum order that also has order
   less than the given bound.
    
   :param graph: the graph on which to find the zero-forcing set
   :param bound: the maximum acceptable order for a zero-forcing set
   :type bound: integer

   :return: a zero-forcing set of minimum order that also has order
      less than the bound if one exists; False if no such zero-forcing
      set can be found

   EXAMPLES::

      sage: from sage.graphs.minrank import zero_forcing_set_bruteforce
      sage: zero_forcing_set_bruteforce(graphs.CompleteGraph(5))
      {0, 1, 2, 3}
      sage: zero_forcing_set_bruteforce(graphs.CompleteGraph(5),2)
      False
   """
    from sage.all import Subsets
    order = graph.order()
    if bound is None:
        bound = order
    if bound < 0:
        bound = 1
    vertices = graph.vertices()
    mindegree = min(graph.degree())
    for i in range(mindegree, bound + 1):
        for subset in Subsets(vertices, i):
            outcome = zerosgame(graph, subset)
            if len(outcome) == order:
                return subset
    return False
示例#7
0
def principal_minors(A, size):
    m = A.nrows()
    n = A.ncols()
    r = min(m, n)
    li = []
    for idx in Subsets(range(r), size):
        idx = list(idx)
        li.append(A.base_ring()(A.matrix_from_rows_and_columns(
            idx, idx).determinant()))
    return li
示例#8
0
def get_way_count(surface_count):
    n = (surface_count + 3) // 2
    factors = [x for x, _ in factor(n)]

    def f(x):
        first_k = (x * (-x % 3) - 2) // 3
        last_k = (n - 2) // 3
        last_k = last_k - (last_k - first_k) % x
        return (last_k - first_k) // x + 1

    return ((n - 2) // 3 + 1 + sum(
        (+1 if len(subset) % 2 == 0 else -1) * f(prod(subset))
        for subset in Subsets(factors) if subset))
示例#9
0
    def padically_evaluate_regular(self, datum):
        if not datum.is_regular():
            raise ValueError('need a regular datum')

        q = var('q')
        count_cap = {}
        N = Set(range(len(datum.polynomials)))

        for I in Subsets(N):
            F = [datum.initials[i].num for i in I]
            V = SubvarietyOfTorus(F, torus_dim=datum.ambient_dim)
            count_cap[I] = V.count()

        for I in Subsets(N):
            cnt = sum((-1)**len(J) * count_cap[I+J] for J in Subsets(N-I))
            if not cnt:
                continue

            I = list(I)
            polytopes = []

            id = identity_matrix(ZZ, len(I))
            def vectorise(k, vec):
                w = id[I.index(k)] if k in I else vector(ZZ,len(I))
                return vector(ZZ, list(vec) + list(w))

            assert len(datum._ideal2poly[0]) == len(datum.ideals[0].gens)
            polytopes = [Polyhedron(vertices=[ vectorise(k, datum.ideals[0].initials[m].exponents()[0]) for m,k in enumerate(datum._ideal2poly[0]) ], ambient_dim=datum.ambient_dim+len(I))]

            extended_RS = datum.RS * RationalSet(StrictlyPositiveOrthant(len(I)))

            foo, ring = symbolic_to_ratfun(cnt * (q - 1)**len(I) / q**datum.ambient_dim, [var('t'), var('q')])
            corr_cnt = CyclotomicRationalFunction.from_laurent_polynomial(foo, ring)

            assert all(extended_RS.ambient_dim == P.ambient_dim() for P in polytopes)

            for z in padically_evaluate_monomial_integral(extended_RS, polytopes, [ (1,), (0,) ]):
                yield corr_cnt * z
示例#10
0
def _res_arr(n):
    from sage.all import Subsets, HyperplaneArrangements, QQ, Matrix
    Subs = Subsets(range(1, n + 1))

    def S_vec(S):
        v = [QQ(0)] * (n + 1)
        for s in S:
            v[s] = QQ(1)
        return v

    M = [S_vec(S) for S in Subs if len(S) > 0]
    HH = HyperplaneArrangements(QQ, tuple(['x' + str(k) for k in range(n)]))
    H = HH(Matrix(QQ, M))
    return H
示例#11
0
def zero_forcing_set_bruteforce(graph, bound=None, all_sets=False):
    """
   Return a zero forcing set of minimum order that also has order
   less than the given bound.
    
   :param graph: the graph on which to find the zero-forcing set
   :param int bound: the maximum acceptable order for a zero-forcing set
   :param bool all_sets: whether to return all zero forcing sets 
       or just the first one

   :return: a zero-forcing set (or list of all zero-forcing sets if all_sets is True)
      of minimum order that also has order less than the bound if one exists; 
      False if no such zero-forcing set can be found.

   EXAMPLES::

      sage: from sage.graphs.minrank import zero_forcing_set_bruteforce
      sage: zero_forcing_set_bruteforce(graphs.CompleteGraph(5))
      {0, 1, 2, 3}
      sage: zero_forcing_set_bruteforce(graphs.CompleteGraph(5),2)
      False
      sage: zero-forcing_set_bruteforce(graphs.CompleteGraph(5), all_sets=True)
      [{0, 1, 2, 3}, {0, 1, 2, 4}, {0, 1, 3, 4}, {0, 2, 3, 4}, {1, 2, 3, 4}]
   """
    from sage.all import Subsets
    order = graph.order()
    if bound is None:
        bound = order
    if bound < 0:
        bound = 1
    found_zfs = False
    zfs_sets = []
    vertices = graph.vertices()
    mindegree = min(graph.degree())
    for i in range(mindegree, bound + 1):
        if found_zfs:
            break
        for subset in Subsets(vertices, i):
            outcome = zerosgame(graph, subset)
            if len(outcome) == order:
                if all_sets:
                    found_zfs = True
                    zfs_sets.append(subset)
                else:
                    return subset
    if found_zfs:
        return zfs_sets
    else:
        return False
示例#12
0
def _mixed_volume_naive(gen):
    """
    Naive computation of the normalised mixed volume using Cox et al.,
    'Using Algebraic Geometry', Thm 7.4.12.
    """
    P = list(gen)
    n = len(P)

    if any(q.ambient_dim() != n for q in P):
        raise TypeError(
            'Number of polytopes and ambient dimension do not match')
    res = 0
    for I in Subsets(range(n)):
        if not I:
            continue
        res += (-1)**len(I) * (sum(P[i] for i in I)).volume()

    return (-1)**n / Integer(factorial(n)) * res
示例#13
0
def is_nondegenerate(F,
                     all_subsets=True,
                     all_initial_forms=True,
                     collision_handler=None):
    # NOTE: Setting all_subsets=False gives exactly Khovanskii's original
    # non-degeneracy condition.

    logger.debug('Original polynomials: %s' % F)
    if not F:
        return True

    if 0 in F:
        raise NotImplementedError()

    for G, _ in relative_initial_forms(F) if all_initial_forms else [(F,
                                                                      None)]:
        # NOTE: we could do the torus factor splitting for each subset separately.
        G, _, _ = split_off_torus(G)
        logger.debug('Restricted polynomials: %s' % G)

        R = G[0].parent()
        jac = jacobian(G, R.gens())

        idx = [i for i in range(len(G)) if not G[i].is_monomial()]
        if not all_subsets and len(idx) < len(G):
            continue  # empty variety!

        logger.debug('Active indices: %s' % idx)
        S = Subsets(idx) if all_subsets else [idx]

        for J in S:
            if not J:
                continue
            I = R.ideal([G[j]
                         for j in J] + matrix(R, [jac[j]
                                                  for j in J]).minors(len(J)))
            if not belongs_to_radical(prod(R.gens()), I):
                logger.debug('Collision: %s' % J)
                if collision_handler is not None:
                    collision_handler(J)
                return False
    return True
示例#14
0
    def height_function(self, vertex_edge_collisions, extra_layers=0, edge_edge_collisions=[]):
        r"""
        Return a height function of edges if possible for given vertex-edge collisions.

        WARNING:
        
        Costly, since it runs through all edge-colorings.
        """
        def e2s(e):
            return Set(e)
        for v in vertex_edge_collisions:
            vertex_edge_collisions[v] = Set([e2s(e) for e in vertex_edge_collisions[v]])
        collision_graph = Graph([[e2s(e) for e in self._graph.edges(labels=False)],[]],format='vertices_and_edges')
        for u in self._graph.vertices():
            collision_graph.add_edges([[e2s([u,v]),e2s([u,w]),''] for v,w in Subsets(self._graph.neighbors(u),2)])
        for e in collision_graph.vertices():
            for v in vertex_edge_collisions:
                if v in e:
                    for f in vertex_edge_collisions[v]:
                        collision_graph.add_edge([e2s(f), e2s(e), 'col'])
        for e, f in edge_edge_collisions:
            collision_graph.add_edge([e2s(f), e2s(e), 'e-e_col'])
        from sage.graphs.graph_coloring import all_graph_colorings
        optimal = False
        chrom_number = collision_graph.chromatic_number()
        for j in range(0, extra_layers + 1):
            i = 1
            res = []
            num_layers = chrom_number + j
            min_s = len(self._graph.vertices())*num_layers
            for col in all_graph_colorings(collision_graph,num_layers):
                if len(Set(col.keys()))<num_layers:
                    continue
                layers = {}
                for h in col:
                    layers[h] = [u for e in col[h] for u in e]
                col_free = True
                A = []
                for v in vertex_edge_collisions:
                    A_min_v = min([h for h in layers if v in layers[h]])
                    A_max_v = max([h for h in layers if v in layers[h]])
                    A.append([A_min_v, A_max_v])
                    for h in range(A_min_v+1,A_max_v):
                        if v not in layers[h]:
                            if len(Set(col[h]).intersection(vertex_edge_collisions[v]))>0:
                                col_free = False
                                break
                    if not col_free:
                        break
                if col_free:
                    s = 0
                    for v in self._graph.vertices():
                        A_min_v = min([h for h in layers if v in layers[h]])
                        A_max_v = max([h for h in layers if v in layers[h]])
                        s += A_max_v - A_min_v
                    if s<min_s:
                        min_s = s
                        res.append((col, s, A))
                        i += 1
                        if s==2*len(self._graph.edges())-len(self._graph.vertices()):
                            optimal = True
                            break
            if optimal:
                break
        if not res:
            return None
        vertex_coloring = min(res, key = lambda t: t[1])[0]
        h = {}
        for layer in  vertex_coloring:
            for e in vertex_coloring[layer]:
                h[e] = layer
        return h
    def __init__(self, graph, four_cycles=[], separator='', edges_ordered=[]):
        if not (isinstance(graph, FlexRiGraph) or 'FlexRiGraph' in str(type(graph))):
            raise exceptions.TypeError('The graph must be of the type FlexRiGraph.')
        self._graph = graph

        if four_cycles == []:
            self._four_cycles = self._graph.four_cycles(only_with_NAC=True) 
        else:
            self._four_cycles = four_cycles

        if not self._graph.are_NAC_colorings_named():
            self._graph.set_NAC_colorings_names()

#        -----Polynomial Ring for leading coefficients-----
        ws = []
        zs = []
        lambdas = []
        ws_latex = []
        zs_latex = []
        lambdas_latex = []
        
        if edges_ordered==[]:
            edges_ordered = self._graph.edges(labels=False)
        else:
            if (Set([self._edge2str(e) for e in edges_ordered]) !=
                Set([self._edge2str(e) for e in self._graph.edges(labels=False)])):
                raise ValueError('The provided ordered edges do not match the edges of the graph.')

        for e in edges_ordered:
            ws.append('w' + self._edge2str(e))
            zs.append('z' + self._edge2str(e))
            lambdas.append('lambda' + self._edge2str(e))
            ws_latex.append('w_{' + self._edge2str(e).replace('_', separator) + '}')
            zs_latex.append('z_{' + self._edge2str(e).replace('_', separator) + '}')
            lambdas_latex.append('\\lambda_{' + self._edge2str(e).replace('_', separator) + '}')

        self._ringLC = PolynomialRing(QQ, names=lambdas+ws+zs) #, order='lex')
        self._ringLC._latex_names = lambdas_latex + ws_latex + zs_latex
        self._ringLC_gens = self._ringLC.gens_dict()

        self._ring_lambdas = PolynomialRing(QQ, names=lambdas + ['u'])
        self._ring_lambdas._latex_names = lambdas_latex + ['u']
        self._ring_lambdas_gens = self._ring_lambdas.gens_dict()
        self.aux_var = self._ring_lambdas_gens['u']
        
        xs = []
        ys = []
        xs_latex = []
        ys_latex = []
        for v in self._graph.vertices():
            xs.append('x' + str(v))
            ys.append('y' + str(v))
            xs_latex.append('x_{' + str(v) + '}')
            ys_latex.append('y_{' + str(v) + '}')
            
        self._ring_coordinates = PolynomialRing(QQ, names=lambdas+xs+ys)
        self._ring_coordinates._latex_names = lambdas_latex + xs_latex + ys_latex
        self._ring_coordinates_gens = self._ring_coordinates.gens_dict()
        
        
#        ----Ramification-----
#         if len(self._graph.NAC_colorings()) > 1: 
        self._ring_ramification = PolynomialRing(QQ,
                                                 [col.name() for col in self._graph.NAC_colorings()],
                                                 len(self._graph.NAC_colorings()))
#         else:
#             self._ring_ramification = PolynomialRing(QQ, self._graph.NAC_colorings()[0].name())
        self._ring_ramification_gens = self._ring_ramification.gens_dict()
        self._restriction_NAC_types = self.NAC_coloring_restrictions()

#        -----Graph of 4-cycles-----
        self._four_cycle_graph = Graph([self._four_cycles,[]], format='vertices_and_edges')

        for c1, c2 in Subsets(self._four_cycle_graph.vertices(), 2):
            intersection = self.cycle_edges(c1, sets=True).intersection(self.cycle_edges(c2, sets=True))
            if len(intersection)>=2 and len(intersection[0].intersection(intersection[1]))==1:
                common_vert = intersection[0].intersection(intersection[1])[0]
                self._four_cycle_graph.add_edge(c1, c2, common_vert)

#        -----Cycle with orthogonal diagonals due to NAC-----
        self._orthogonal_diagonals = {
                delta.name(): [cycle for cycle in self._four_cycle_graph if delta.cycle_has_orthogonal_diagonals(cycle)]
                for delta in self._graph.NAC_colorings()}
示例#16
0
from sage.all import vector, Combinations, Subsets, Set, SimplicialComplex, ZZ, ChainComplex, save
from CatMat import FiniteCategory, CatMat, dgModule, TerminalCategory
from Prune import prune_dg_module_on_poset

n = 3
verbose = True

# Set up our graphs
vertices = range(1, n + 1)
edges = [(i, j) for i, j in Combinations(vertices, 2)]
graphs = list(Subsets(edges))


# Define the poset G(n) as a category
def G_one(x):
    return '*'


def G_hom(x, y):
    if x.issubset(y):
        return ['*']
    return []


def G_comp(x, f, y, g, z):
    return '*'


G = FiniteCategory(graphs, G_one, G_hom, G_comp)
Gop = G.op()
示例#17
0
    def topologically_evaluate_regular(self, datum):
        T = datum.toric_datum
        if not T.is_regular():
            raise ValueError('Can only processed regular toric data')

        # All our polyhedra all really half-open cones (with a - 1 >=0
        # being an imitation of a >= 0).

        C = conify_polyhedron(T.polyhedron)

        M = Set(range(T.length()))

        logger.debug('Dimension of polyhedron: %d' % T.polyhedron.dim())

        # STEP 1:
        # Compute the Euler characteristcs of the subvarieties of
        # Torus^sth defined by some subsets of T.initials.
        # Afterwards, we'll combine those into Denef-style Euler characteristics
        # via inclusion-exclusion.

        logger.debug('STEP 1')

        alpha = {}
        tdim = {}

        for I in Subsets(M):
            logger.debug('Processing I = %s' % I)
            F = [T.initials[i] for i in I]

            V = SubvarietyOfTorus(F, torus_dim=T.ambient_dim)
            U, W = V.split_off_torus()

            # Keep track of the dimension of the torus factor for F == 0.
            tdim[I] = W.torus_dim

            if tdim[I] > C.dim():
                # In this case, we will never need alpha[I].
                logger.debug('Totally irrelevant intersection.')
                # alpha[I] = ZZ(0)
            else:
                # To ensure that the computation of Euler characteristics succeeds in case
                # of global non-degeneracy, we test this first.
                # The 'euler_characteristic' method may change generating sets,
                # possibly introducing degeneracies.
                alpha[I] = U.khovanskii_characteristic() if U.is_nondegenerate(
                ) else U.euler_characteristic()
                logger.debug(
                    'Essential Euler characteristic alpha[%s] = %d; dimension of torus factor = %d'
                    % (I, alpha[I], tdim[I]))

        logger.debug(
            'Done computing essential Euler characteristics of intersections: %s'
            % alpha)

        # STEP 2:
        # Compute the topological zeta functions of the extended cones.
        # That is, add extra variables, add variable constraints (here: just >= 0),
        # and add newly monomialised conditions.

        def cat(u, v):
            return vector(list(u) + list(v))

        logger.debug('STEP 2')
        for I in Subsets(M):
            logger.debug('Current set: I = %s' % I)

            # P = C_0 x R_(>0)^I in the paper
            P = DirectProductOfPolyhedra(T.polyhedron,
                                         StrictlyPositiveOrthant(len(I)))

            it = iter(identity_matrix(ZZ, len(I)).rows())
            ieqs = []
            for i in M:
                # Turn lhs[i] | monomial of initials[i] * y[i] if in I,
                #      lhs[i] | monomial of initials[i] otherwise
                # into honest cone conditions.
                ieqs.append(
                    cat(
                        vector(ZZ, (0, )),
                        cat(
                            vector(ZZ, T.initials[i].exponents()[0]) -
                            vector(ZZ, T.lhs[i].exponents()[0]),
                            next(it) if i in I else zero_vector(ZZ, len(I)))))

            if not ieqs:
                # For some reason, not providing any constraints yields the empty
                # polyhedron in Sage; it should be all of RR^whatever, IMO.
                ieqs = [vector(ZZ, (T.ambient_dim + len(I) + 1) * [0])]

            Q = Polyhedron(ieqs=ieqs,
                           base_ring=QQ,
                           ambient_dim=T.ambient_dim + len(I))

            sigma = conify_polyhedron(P.intersection(Q))
            logger.debug('Dimension of Hensel cone: %d' % sigma.dim())

            # Obtain the desired Euler characteristic via inclusion-exclusion,
            # restricted to those terms contributing to the constant term mod q-1.
            chi = sum((-1)**len(J) * alpha[I + J] for J in Subsets(M - I)
                      if tdim[I + J] + len(I) == sigma.dim())

            if not chi:
                continue

            # NOTE: dim(P) = dim(sigma): choose any point omega in P
            # then a large point lambda in Pos^I will give (omega,lambda) in sigma.
            # Moreover, small perturbations of (omega,lambda) don't change that
            # so (omega,lambda) is an interior point of sigma inside P.

            surfs = (topologise_cone(
                sigma,
                matrix([
                    cat(T.integrand[0], zero_vector(ZZ, len(I))),
                    cat(T.integrand[1], vector(ZZ,
                                               len(I) * [-1]))
                ]).transpose()))

            for S in surfs:
                yield SURF(scalar=chi * S.scalar, rays=S.rays)
    def check_orthogonal_diagonals(self, motion_types,  active_NACs, extra_cycles_orthog_diag=[]):
        r"""
        Check the necessary conditions for orthogonal diagonals.

        TODO:
        
        return orthogonality_graph
        """
        perp_by_NAC = [cycle for delta in active_NACs for cycle in self._orthogonal_diagonals[delta]]
        deltoids = [cycle for cycle, t in motion_types.items() if t in ['e','o']]

        orthogonalLines = []
        for perpCycle in perp_by_NAC + deltoids + extra_cycles_orthog_diag:
            orthogonalLines.append(Set([Set([perpCycle[0],perpCycle[2]]), Set([perpCycle[1],perpCycle[3]])]))

        orthogonalityGraph = Graph(orthogonalLines, format='list_of_edges', multiedges=False)
        n_edges = -1

        while  n_edges != orthogonalityGraph.num_edges():
            n_edges = orthogonalityGraph.num_edges()
            for perp_subgraph in orthogonalityGraph.connected_components_subgraphs():
                isBipartite, partition = perp_subgraph.is_bipartite(certificate=True)
                if isBipartite:
                    graph_0 = Graph([v.list() for v in partition if partition[v]==0])
                    graph_1 = Graph([v.list() for v in partition if partition[v]==1])
                    for comp_0 in graph_0.connected_components():
                        for comp_1 in graph_1.connected_components():
                            for e0 in Subsets(comp_0,2):
                                for e1 in Subsets(comp_1,2):
                                    orthogonalityGraph.add_edge([Set(e0), Set(e1)])
                else:
                    raise exceptions.RuntimeError('A component of the orthogonality graph is not bipartite!')

        self._orthogonality_graph = orthogonalityGraph
        check_again = False
        H = {self._edge_ordered(u,v):None for u,v in self._graph.edges(labels=False)}
        self._set_same_lengths(H, motion_types)

        for c in motion_types:
            if not orthogonalityGraph.has_edge(Set([c[0],c[2]]),Set([c[1],c[3]])):
                continue
            if motion_types[c]=='a':       # inconsistent since antiparallel motion cannot have orthogonal diagonals
                return False
            elif motion_types[c]=='p':     # this cycle must be rhombus
                self._set_two_edge_same_lengths(H, c[0], c[1], c[2], c[3], 0)
                self._set_two_edge_same_lengths(H, c[0], c[1], c[1], c[2], 0)
                self._set_two_edge_same_lengths(H, c[0], c[1], c[0], c[3], 0)
                check_again = True

        for c in motion_types:
            if motion_types[c]=='g':
                labels = [H[self._edge_ordered(c[i-1],c[i])] for i in range(0,4)]
                if (not None in labels
                    and ((len(Set(labels))==2 and labels.count(labels[0])==2)
                        or len(Set(labels))==1)):
                    return False
                if (orthogonalityGraph.has_edge(Set([c[0],c[2]]),Set([c[1],c[3]]))
                    and True in [(H[self._edge_ordered(c[i-1], c[i])]==H[self._edge_ordered(c[i-2], c[i-1])]
                                  and H[self._edge_ordered(c[i-1],c[i])]!= None) for i in range(0,4)]):
                    return False

        if check_again:
            for K23_edges in [Graph(self._graph).subgraph(k23_ver).edges(labels=False) for k23_ver in self._graph.induced_K23s()]:
                if MotionClassifier._same_edge_lengths(H, K23_edges):
                    return False

        return True