Esempio n. 1
0
def jordan_blocks_2(S):
    '''
    S: half integral matrix
    Returns the instance of JordanBlocks attached to
    a list of tuples (a, b)
    `a' is a integer which represents an exponent.
    `b' corresponds a quadratic form with size <= 2,
    that is, `b' is in [1, 3, 5, 7] or is equal to
    strings 'h' or 'y'.
    If `b' is equal to 'h', then the gram matrix of
    the corresponding quadratic form is equal to
    matrix([[0, 1/2], [1/2, 0]]).
    If `b' is equal to 'y', then the gram matrix of
    the corresponding quadratic form is equal to
    matrix([[1, 1/2], [1/2, 1]]).
    If `b' is in [1, 3, 5, 7], then the corresponding
    gram matrix is equal to matrix([[b]]).
    These tuples are sorted so that assumptions of Theorem 4.1 or Theorem 4.2
    hold.
    '''
    ls = _jordan_decomposition_2(S)
    # ls is a list of jordan blocks but it may contain diagonal entries of
    # units of length >= 3.
    # We take another jordan blocks by _trans_jordan_dec_2.
    res = [(a, b) for a, b in ls if isinstance(b, str)]
    diag_elts = [(a, b) for a, b in ls if not isinstance(b, str)]
    for a, us_w_idx in list_group_by(diag_elts, lambda x: x[0]):
        l = _trans_jordan_dec_2([_b for _, _b in us_w_idx])
        for b in l:
            if isinstance(b, str):
                res.append((a + 1, b))
            else:
                res.append((a, b))
    # Sort the result so that assumptions of Theorem 4.1 and 4.2 hold.
    non_diags = ("h", "y")
    res1 = []
    for _, blcs in sorted(list_group_by(res, lambda x: x[0]),
                          key=lambda x: -x[0]):
        unit_diags = [(a, qf) for a, qf in blcs if qf not in non_diags]
        non_unit_diags = [(a, qf) for a, qf in blcs if qf in non_diags]
        blcs = unit_diags + non_unit_diags
        res1.extend(blcs)
    return JordanBlocks(res1, two)
Esempio n. 2
0
    def group_by_reduced_forms(self):
        '''
        In list(self), we define equivalent relation ~ by
        t1, t2 in list(self),
        rank(t1) == rank(t2)
        and
        if rank(t1) == 0,
        t1 ~ t2, if and only if t2 == (0, 0, 0)
        if rank(t1) == 1,
        t1 ~ t2, if and only if gcd(t1) == gcd(t2),
        if rank(t1) == 2,
        t1 ~ t2 if and only if reduced forms of t1 and t2 are
        equal.

        Then this function returns a dictionary such that
        rep => equiv_class
        where rep is an element of representatives of this equivalent class
        and equiv_class is a equivalent class that contains rep.
        '''
        r0 = []
        r1 = []
        r2 = []
        for t in self:
            n, r, m = t
            if t == (0, 0, 0):
                r0.append(t)
            elif 4 * n * m - r ** 2 == 0:
                r1.append(t)
            else:
                r2.append(t)
        res0 = {(0, 0, 0): set(r0)}
        res1 = {ls[0]: ls for k, ls in
                list_group_by(r1, lambda t: gcd([QQ(x) for x in t]))}
        res2 = {ls[0]: ls for k, ls in
                list_group_by(r2, lambda x: reduced_form_with_sign(x)[0])}
        res = {}
        for dct in [res0, res1, res2]:
            res.update(dct)
        return res
Esempio n. 3
0
 def group_by_reduced_forms_with_sgn(self):
     '''
     Returns a dictionary whose keys are representatives of equivalent class
     of list(self.pos_defs()).
     Its value at (n, r, m) is the list of
     ((n1, r1, m1), sgn) where (n1, r1, m1) is unimodular equivalent to
     (n, r, m) and sgn is 1 if reduced_form_with_sign((n, r, m))[0]
     is (n1, r1, m1) and reduced_form_with_sign((n, r, m))[1] == 1
     otherwise -1.
     '''
     pos_forms = []
     for t in self.pos_defs():
         rdf, sgn = reduced_form_with_sign(t)
         pos_forms.append((t, rdf, sgn))
     grpd_by_rdf = list_group_by(pos_forms, lambda x: x[1])
     res = {}
     for _, ls in grpd_by_rdf:
         a_tupl, _, a_sgn = ls[0]
         res[a_tupl] = [(t, _sgn * a_sgn) for t, _, _sgn in ls]
     return res
Esempio n. 4
0
    def _inverse(self):
        a = self[(0, 0, 0)]
        if a == 0:
            raise ZeroDivisionError
        prec = self.prec
        R = self.base_ring
        if a != R(1):
            return (self * a ** (-1))._inverse() * a ** (-1)
        res_dict = {(0, 0, 0): R(1)}

        def norm(t):
            return t[0] + t[2]

        prec_dict = dict(list_group_by(list(prec), norm))
        prec_d_keys = sorted(prec_dict.keys())[1:]
        for a in prec_d_keys:
            for t in prec_dict[a]:
                l = list(_spos_def_mats_lt(t))
                l.remove(t)
                res_dict[t] = - sum([res_dict[u] *
                                     self[(t[0] - u[0],
                                           t[1] - u[1],
                                           t[2] - u[2])] for u in l])
        return QexpLevel1(res_dict, prec, base_ring=self.base_ring)