Ejemplo n.º 1
0
    def __init__(self, data, coxeter=None, mutation_type=None, depth=infinity):

        data = copy(data)

        if isinstance(data, Matrix):
            if not data.is_skew_symmetrizable():
                raise ValueError(
                    "The input must be a skew symmetrizable integer matrix")
            self.B0 = data
            self.rk = self.B0.ncols()

        elif isinstance(data, CartanType_abstract):
            self.rk = data.rank()

            if Set(data.index_set()) != Set(range(self.rk)):
                relabelling = dict(zip(data.index_set(), range(self.rk)))
                data = data.relabel(relabelling)

            self.cartan_type.set_cache(data)

            if coxeter == None:
                coxeter = range(self.rk)
            if Set(coxeter) != Set(data.index_set()):
                raise ValueError(
                    "The Coxeter element need to be a list permuting the entries of the index set of the Cartan type"
                )
            self.coxeter.set_cache(copy(coxeter))

            self.cartan_companion.set_cache(data.cartan_matrix())
            self.B0 = 2 - self.cartan_companion()

            for i in range(self.rk):
                for j in range(i, self.rk):
                    a = coxeter[j]
                    b = coxeter[i]
                    self.B0[a, b] = -self.B0[a, b]

        elif type(data) in [
                QuiverMutationType_Irreducible, QuiverMutationType_Reducible
        ]:
            self.__init__(data.b_matrix(), mutation_type=data, depth=depth)

        elif type(data) == list:
            self.__init__(CartanType(data), coxeter=coxeter, depth=depth)

        else:
            raise ValueError("Input is not valid")

        # this is a hack to deal with type ['D', n, 1] since mutation_type()
        # can't distinguish it
        if mutation_type:
            self.mutation_type.set_cache(QuiverMutationType(mutation_type))

        self._depth = depth
Ejemplo n.º 2
0
    def small_prime_value(self, Bmax=1000):
        r"""
        Returns a prime represented by this (primitive positive definite) binary form.

        INPUT:

        - ``Bmax`` -- a positive bound on the representing integers.

        OUTPUT:

        A prime number represented by the form.

        .. NOTE::

            This is a very elementary implementation which just substitutes
            values until a prime is found.

        EXAMPLES::

            sage: [Q.small_prime_value() for Q in BinaryQF_reduced_representatives(-23, primitive_only=True)]
            [23, 2, 2]
            sage: [Q.small_prime_value() for Q in BinaryQF_reduced_representatives(-47, primitive_only=True)]
            [47, 2, 2, 3, 3]
        """
        from sage.sets.all import Set
        from sage.arith.srange import xsrange
        B = 10
        while True:
            llist = list(Set([self(x,y) for x in xsrange(-B,B) for y in xsrange(B)]))
            llist = sorted([l for l in llist if l.is_prime()])
            if llist:
                return llist[0]
            if B >= Bmax:
                raise ValueError("Unable to find a prime value of %s" % self)
            B += 10
Ejemplo n.º 3
0
 def _tube_nbh(self, alpha):
     sup_a = self._tube_support(alpha)
     nbh_a = [self.tau_c(x) for x in sup_a if self.tau_c(x) not in sup_a]
     nbh_a += [
         self.tau_c_inverse(x) for x in sup_a
         if self.tau_c_inverse(x) not in sup_a
     ]
     nbh_a = Set(nbh_a)
     return tuple(nbh_a)
Ejemplo n.º 4
0
    def clusters(self, depth=None):
        r"""
        FIXME: handle error id depth is not set
        """
        if depth == None:
            depth = self._depth
        if self._clusters[0] != depth:

            def compatible_following(l):
                out = []
                while l:
                    x = l.pop()
                    comp_with_x = [
                        y for y in l if self.compatibility_degree(x, y) == 0
                    ]
                    if comp_with_x != []:
                        out.append((x, comp_with_x))
                    else:
                        out.append((x, ))
                return out

            d_vectors = self.d_vectors(depth=depth)
            clusters = compatible_following(d_vectors)
            done = False
            while not done:
                new = []
                done = True
                for clus in clusters:
                    if type(clus[-1]) == list:
                        done = False
                        for y in compatible_following(clus[-1]):
                            new.append(clus[:-1] + y)
                    else:
                        new.append(clus)
                clusters = copy(new)
            self._clusters = [
                depth, [Set(x) for x in clusters if len(x) == self._n]
            ]

        return copy(self._clusters[1])
Ejemplo n.º 5
0
def _global_relation_matrix(precision, S, weight_parity):
    r"""
    Deduce restrictions on the coefficients of a Jacobi form based on
    the specialization to Jacobi form of scalar index.
    
    INPUT:
    
    - ``precision`` -- An instance of JacobiFormD1Filter.
    
    - `S` -- A list of vectors.
    
    - ``weight_parity`` -- The parity of the weight of the considered Jacobi forms.
    """
    L = precision.jacobi_index()
    weight_parity = weight_parity % 2

    (mat, row_groups, row_labels,
     column_labels) = _global_restriction_matrix(precision,
                                                 S,
                                                 weight_parity,
                                                 find_relations=True)

    reduced_index_indices = dict((m, JacobiFormD1NNIndices(m)) for m in Set(
        m for (_, m, _, _) in row_groups))

    relations = list()
    for (s, m, start, length) in row_groups:
        row_labels_dict = row_labels[m]
        for (l, i) in row_labels_dict.iteritems():
            (lred, sign) = reduced_index_indices[m].reduce(l)
            if lred == l:
                continue

            relations.append(
                mat.row(start + row_labels_dict[lred]) -
                (1 if weight_parity == 0 else sign) * mat.row(start + i))

    return (matrix(len(relations), len(column_labels),
                   relations), column_labels)
Ejemplo n.º 6
0
def _test__coefficient_by_restriction(precision,
                                      k,
                                      relation_precision=None,
                                      additional_lengths=1):
    r"""
    TESTS::
    
        sage: from psage.modform.jacobiforms.jacobiformd1_fourierexpansion import *
        sage: from psage.modform.jacobiforms.jacobiformd1_fegenerators import _test__coefficient_by_restriction

    ::

        sage: indices = JacobiFormD1Indices(QuadraticForm(matrix(2, [2,1,1,2])))
        sage: precision = indices.filter(10)
        sage: _test__coefficient_by_restriction(precision, 10, additional_lengths = 10)
        
    ::

        sage: indices = JacobiFormD1Indices(QuadraticForm(matrix(2, [4,1,1,2])))
        sage: precision = JacobiFormD1Filter(5, indices.jacobi_index())
        sage: _test__coefficient_by_restriction(precision, 40, additional_lengths = 4) # long test
        
    We use different precisions for relations and restrictions::

        sage: indices = JacobiFormD1Indices(QuadraticForm(matrix(2, [2,1,1,2])))
        sage: precision = indices.filter(20)
        sage: relation_precision = indices.filter(2)
        sage: _test__coefficient_by_restriction(precision, 10, relation_precision, additional_lengths = 4)
    """
    from sage.misc.misc import verbose

    L = precision.jacobi_index()

    if relation_precision is not None and not relation_precision <= precision:
        raise ValueError(
            "Relation precision must be less than or equal to precision.")

    expansions = _coefficient_by_restriction(precision, k, relation_precision)
    verbose(
        "Start testing restrictions of {2} Jacobi forms of weight {0} and index {1}"
        .format(k, L, len(expansions)))

    ch1 = JacobiFormD1WeightCharacter(k)
    chL = JacobiFormD1WeightCharacter(k, L.matrix().nrows())

    R = precision.monoid()._r_representatives
    S_extended = _find_complete_set_of_restriction_vectors(L, R)

    S = list()
    for (s, _) in S_extended:
        if s not in S:
            S.append(s)
    max_S_length = max([L(s) for s in S])

    S = L.short_vector_list_up_to_length(max_S_length + 1 + additional_lengths,
                                         True)[1:]
    Sold = flatten(S[:max_S_length + 1], max_level=1)
    Snew = flatten(S[max_S_length + 1:], max_level=1)
    S = flatten(S, max_level=1)
    verbose("Will use the following restriction vectors: {0}".format(S))

    jacobi_forms_dict = dict()
    non_zero_expansions = list()
    for s in S:
        m = L(s)
        verbose("Restriction to index {0} via {1}".format(m, s))

        try:
            jacobi_forms = jacobi_forms_dict[m]
        except KeyError:
            jacobi_forms = JacobiFormsD1NN(
                QQ, JacobiFormD1NNGamma(k, m),
                JacobiFormD1NNFilter(precision.index(), m))
            jacobi_forms_dict[m] = jacobi_forms
        jacobi_forms_module = span([
            vector(b[(ch1, k)]
                   for k in jacobi_forms.fourier_expansion_precision())
            for b in map(lambda b: b.fourier_expansion(),
                         jacobi_forms.graded_submodule(None).basis())
        ])

        fourier_expansion_module = jacobi_forms.fourier_expansion_ambient()

        for (i, expansion) in enumerate(expansions):
            verbose("Testing restriction of {0}-th form".format(i))
            restricted_expansion_dict = dict()
            for (n, r) in precision.monoid_filter():
                rres = s.dot_product(vector(r))
                try:
                    restricted_expansion_dict[(n, rres)] += expansion[(chL,
                                                                       (n, r))]
                except KeyError:
                    restricted_expansion_dict[(n, rres)] = expansion[(chL,
                                                                      (n, r))]

            restricted_expansion = vector(
                restricted_expansion_dict.get(k, 0)
                for k in jacobi_forms.fourier_expansion_precision())
            if restricted_expansion not in jacobi_forms_module:
                raise RuntimeError(
                    "{0}-th restricted via {1} is not a Jacobi form".format(
                        i, s))

            if restricted_expansion != 0:
                non_zero_expansions.append(i)

    assert Set(non_zero_expansions) == Set(range(len(expansions)))
Ejemplo n.º 7
0
def _global_restriction_matrix(precision,
                               S,
                               weight_parity,
                               find_relations=False):
    r"""
    A matrix that maps the Fourier expansion of a Jacobi form of given precision
    to their restrictions with respect to the elements of S.
    
    INPUT:
    
    - ``precision`` -- An instance of JacobiFormD1Filter.
    
    - `S` -- A list of vectors.
    
    - ``weight_parity`` -- The parity of the weight of the considered Jacobi forms.
    
    - ``find_relation`` -- A boolean. If ``True``, then the restrictions to
                           nonreduced indices will also be computed.
                           
    TESTS::
    
        sage: from psage.modform.jacobiforms.jacobiformd1_fourierexpansion import *
        sage: from psage.modform.jacobiforms.jacobiformd1_fegenerators import _global_restriction_matrix
        sage: precision = JacobiFormD1Filter(5, QuadraticForm(matrix(2, [2,1,1,2])))
        sage: (global_restriction_matrix, row_groups, row_labels, column_labels) = _global_restriction_matrix(precision, [vector((1,0))], 12)
        sage: global_restriction_matrix
        [1 0 0 0 0 0 0 0 0]
        [0 1 2 0 0 0 0 0 0]
        [2 0 2 0 0 0 0 0 0]
        [0 0 2 1 2 0 0 0 0]
        [0 2 0 0 2 0 0 0 0]
        [2 0 0 0 2 1 2 0 0]
        [0 0 2 2 0 0 2 0 0]
        [0 2 0 0 0 0 2 1 2]
        [0 0 0 0 2 2 0 0 2]
        sage: (row_groups, row_labels, column_labels)
        ([((1, 0), 1, 0, 9)], {1: {(0, 0): 0, (3, 0): 5, (3, 1): 6, (2, 1): 4, (2, 0): 3, (1, 0): 1, (4, 1): 8, (1, 1): 2, (4, 0): 7}}, [(0, (0, 0)), (1, (0, 0)), (1, (1, 1)), (2, (0, 0)), (2, (1, 1)), (3, (0, 0)), (3, (1, 1)), (4, (0, 0)), (4, (1, 1))])
    """
    L = precision.jacobi_index()
    weight_parity = weight_parity % 2

    jacobi_indices = [L(s) for s in S]
    index_filters = dict(
        (m,
         list(
             JacobiFormD1NNFilter(
                 precision.index(), m, reduced=not find_relations)))
        for m in Set(jacobi_indices))

    column_labels = list(precision)
    reductions = dict((l, list()) for l in column_labels)
    for l in precision.monoid_filter():
        (lred, sign) = precision.monoid().reduce(l)
        reductions[lred].append((l, sign))

    row_groups = [len(index_filters[m]) for m in jacobi_indices]
    row_groups = [(s, m, sum(row_groups[:i]), row_groups[i])
                  for ((i, s), m) in zip(enumerate(S), jacobi_indices)]
    row_labels = dict((m, dict((l, i)
                               for (i, l) in enumerate(index_filters[m])))
                      for m in Set(jacobi_indices))
    dot_products = [
        cython_lambda(
            ' , '.join(['int x{0}'.format(i) for i in range(len(s))]),
            ' + '.join(['{0} * x{1}'.format(s[i], i) for i in range(len(s))]))
        for (s, _, _, _) in row_groups
    ]

    restriction_matrix = zero_matrix(ZZ, row_groups[-1][2] + row_groups[-1][3],
                                     len(column_labels))

    for (cind, l) in enumerate(column_labels):
        for ((n, r), sign) in reductions[l]:
            for ((s, m, start, length),
                 dot_product) in zip(row_groups, dot_products):
                row_labels_dict = row_labels[m]
                try:
                    restriction_matrix[start + row_labels_dict[(n, dot_product(*r))], cind] \
                      += 1 if weight_parity == 0 else sign
                except KeyError:
                    pass

    return (restriction_matrix, row_groups, row_labels, column_labels)
Ejemplo n.º 8
0
def _find_complete_set_of_restriction_vectors(L,
                                              R,
                                              additional_s=0,
                                              reduction_function=None):
    r"""
    Given a set R of elements in L^# (e.g. representatives for ( L^# / L ) / \pm 1)
    find a complete set of restriction vectors. (See [GKR])
    
    INPUT:
    
    - `L` -- A quadratic form.
    
    - `R` -- A list of tuples or vectors in L \otimes QQ (with
             given coordinates).

    - ``additional_s`` -- A non-negative integer; Number of additional
                          elements of `L` that should be returned.
    
    - ``reduction_function`` -- A function that takes a tuple representing an element in `L^\#`
                                and returs a pair of a reduced element in `L^\#` and a sign.
    
    OUTPUT:
    
    - A set S of pairs, the first of which is a vector corresponding to
      an element in L, and the second of which is an integer.
    
    TESTS::
    
        sage: from psage.modform.jacobiforms.jacobiformd1_fegenerators import _find_complete_set_of_restriction_vectors
        sage: from psage.modform.jacobiforms.jacobiformd1_fourierexpansion import *
        sage: indices = JacobiFormD1Indices(QuadraticForm(matrix(2, [2,1,1,2])))
        sage: _find_complete_set_of_restriction_vectors(indices.jacobi_index(), indices._r_representatives)
        [((1, 0), 0), ((1, 0), 1), ((-2, 1), 1)]
        sage: _find_complete_set_of_restriction_vectors(indices.jacobi_index(), indices._r_representatives, reduction_function = indices.reduce_r)
        [((1, 0), 0), ((1, 0), 1), ((-2, 1), 1)]
        
    ::
     
        sage: from psage.modform.jacobiforms.jacobiformd1_fegenerators import _local_restriction_matrix
        sage: indices = JacobiFormD1Indices(QuadraticForm(matrix(4, [2,0,0,1, 0,2,0,1, 0,0,2,1, 1,1,1,2])))
        sage: S = _find_complete_set_of_restriction_vectors(indices.jacobi_index(), indices._r_representatives)
        sage: _local_restriction_matrix(indices._r_representatives, S).rank()
        4
    """
    R = [map(vector, rs) for rs in R]

    length_inc = 5
    max_length = 5
    cur_length = 1
    short_vectors = L.short_vector_list_up_to_length(max_length, True)

    S = list()
    restriction_space = FreeModule(QQ, len(R)).span([])

    while (len(S) < len(R) + additional_s):
        while len(short_vectors[cur_length]) == 0:
            cur_length += 1
            if max_length >= cur_length:
                max_length += length_inc
                short_vectors = L.short_vector_list_up_to_length(
                    max_length, True)

        s = vector(short_vectors[cur_length].pop())

        rcands = Set([s.dot_product(r) for rs in R for r in rs])

        for r in rcands:
            v = _eval_restriction_vector(R, s, r, reduction_function)
            if len(S) - restriction_space.rank() < additional_s \
              or v not in restriction_space :
                S.append((s, r))
                restriction_space = restriction_space + FreeModule(
                    QQ, len(R)).span([v])

                if len(S) == len(R) + additional_s:
                    break

    return S
Ejemplo n.º 9
0
                                                      row_groups__small):
            row_labels_dict = row_labels__small[L(s)]
            row_indices__sub = length_small * [None]
            for (l, (i, i_pre)) in row_labels_dict.iteritems():
                row_indices__sub[i] = start + i_pre
            row_indices__small += row_indices__sub

        global_restriction_matrix = global_restriction_matrix__big.matrix_from_rows_and_columns(
            row_indices__small,
            [column_labels.index(l) for l in column_labels_relations])
    else:
        global_restriction_matrix = global_restriction_matrix__big

    jacobi_indices = [m for (_, m, _, _) in row_groups]
    index_filters = dict((m, JacobiFormD1NNFilter(precision.index(), m))
                         for m in Set(jacobi_indices))
    jacobi_forms = dict(
        (m, JacobiFormsD1NN(QQ, JacobiFormD1NNGamma(k, m), prec))
        for (m, prec) in index_filters.iteritems())

    forms = list()
    nmb_forms_coords = row_groups[-1][2] + row_groups[-1][3]
    ch1 = JacobiFormD1WeightCharacter(k)
    for (s, m, start, length) in row_groups:
        row_labels_dict = row_labels[m]
        for f in jacobi_forms[m].graded_submodule(None).basis():
            f = f.fourier_expansion()
            v = vector(ZZ, len(row_labels_dict))
            for (l, i) in row_labels_dict.iteritems():
                v[i] = f[(ch1, l)]
Ejemplo n.º 10
0
    def cartan_type(self):
        r"""
        Returns the Cartan type of the Cartan companion of self.b_matrix()

        Only crystallographic types are implemented

        Warning: this function is redundant but the corresonding method in
        CartanType does not recognize all the types
        """
        A = self.cartan_companion()
        n = self.rk
        degrees_dict = dict(zip(range(n), map(sum, 2 - A)))
        degrees_set = Set(degrees_dict.values())

        types_to_check = [["A", n]]
        if n > 1:
            types_to_check.append(["B", n])
        if n > 2:
            types_to_check.append(["C", n])
        if n > 3:
            types_to_check.append(["D", n])
        if n >= 6 and n <= 8:
            types_to_check.append(["E", n])
        if n == 4:
            types_to_check.append(["F", n])
        if n == 2:
            types_to_check.append(["G", n])
        if n > 1:
            types_to_check.append(["A", n - 1, 1])
            types_to_check.append(["B", n - 1, 1])
            types_to_check.append(["BC", n - 1, 2])
            types_to_check.append(["A", 2 * n - 2, 2])
            types_to_check.append(["A", 2 * n - 3, 2])
        if n > 2:
            types_to_check.append(["C", n - 1, 1])
            types_to_check.append(["D", n, 2])
        if n > 3:
            types_to_check.append(["D", n - 1, 1])
        if n >= 7 and n <= 9:
            types_to_check.append(["E", n - 1, 1])
        if n == 5:
            types_to_check.append(["F", 4, 1])
        if n == 3:
            types_to_check.append(["G", n - 1, 1])
            types_to_check.append(["D", 4, 3])
        if n == 5:
            types_to_check.append(["E", 6, 2])

        for ct_name in types_to_check:
            ct = CartanType(ct_name)
            if 0 not in ct.index_set():
                ct = ct.relabel(dict(zip(range(1, n + 1), range(n))))
            ct_matrix = ct.cartan_matrix()
            ct_degrees_dict = dict(zip(range(n), map(sum, 2 - ct_matrix)))
            if Set(ct_degrees_dict.values()) != degrees_set:
                continue
            for p in Permutations(range(n)):
                relabeling = dict(zip(range(n), p))
                ct_new = ct.relabel(relabeling)
                if ct_new.cartan_matrix() == A:
                    return copy(ct_new)
        raise ValueError("Type not recognized")