Esempio n. 1
0
 def inv_op_unit(self, tag, d, j):
     if tag == 'X':
         tag1 = 'X'
         d1 = d ^ self.lin_d[0]
         j1 = j
         sign = (self.sign_XYZ[d] & 1)
         sign ^= (self.lin_i[0] >> j) & 1
         if self.odd:
             cc = m24.vect_to_cocode(1 << j)
             sign ^= m24.scalar_prod(d, cc)
     elif tag in 'ZY':
         s = self.odd ^ (tag == 'Y')
         tag1 = 'ZY'[s]
         s += 1
         d1 = d ^ self.lin_d[s]
         j1 = j
         sign = (self.sign_XYZ[d] >> s) & 1
         sign ^= (self.lin_i[s] >> j) & 1
     elif tag == 'T':
         tag1 = 'T'
         d1 = d
         te = self.s_T[d]
         so_exp = _as_suboctad(self.f, d)
         assert te & 0x3f == so_exp, (hex(te), hex(so_exp))
         j1 = j ^ (te & 0x3f)
         sign = m24.suboctad_scalar_prod(j, (te >> 8) & 0x3f)
         sign ^= (te >> 14) & 1
         sign ^= m24.suboctad_weight(j) & self.odd & 1
         assert ((te >> 15) ^ self.odd) & 1 == 0
     else:
         raise ValueError("Illegal tag " + str(tag))
     return sign & 1, tag1, d1, j1
Esempio n. 2
0
def mul_Tp(tag, octad, sub, g):
    d = m24.octad_to_gcode(octad)
    c = m24.suboctad_to_cocode(sub, d)
    eps, pi, rep = g.cocode, g.perm, g.rep
    d1 = m24.op_ploop_autpl(d, rep)
    c1 = m24.op_cocode_perm(c, pi)
    s = d1 >> 12
    s ^= (eps >> 11) & 1 & m24.suboctad_weight(sub)
    octad1 = m24.gcode_to_octad(d1)
    sub1 = m24.cocode_to_suboctad(c1, d1)
    return s, tag, octad1, sub1
Esempio n. 3
0
def test_octads():
    print("")
    OMEGA = ~PLoop(0)
    for i in range(200):
        no = randint(0, 758)
        o = Octad(no)
        assert o == PLoop(mat24.octad_to_gcode(no))
        assert o == Octad(sample(o.bit_list, 5))
        assert o.octad == no
        o_signbit, o_cpl = randint(0, 1), randint(0, 1)
        signed_o = PLoopZ(o_signbit, o_cpl) * o
        assert signed_o.octad == no
        assert signed_o.sign == (-1)**o_signbit
        assert o.gcode == mat24.octad_to_gcode(no)
        assert signed_o.gcode == (o * PLoopZ(0, o_cpl)).gcode
        assert signed_o.split_octad() == (o_signbit, o_cpl, o)
        nsub = randint(0, 63)
        sub = (-1)**o_signbit * SubOctad(no, nsub)
        sub1 = (-1)**o_signbit * SubOctad(o, nsub)
        sub_weight = mat24.suboctad_weight(nsub)
        assert sub == sub1
        assert o == (-1)**o_signbit * Octad(sub) * OMEGA**sub_weight
        assert sub.octad_number() == no
        ploop, cocode = sub.isplit()
        sign, gcode = (-1)**(ploop >> 12), ploop & 0xfff
        assert gcode == o.gcode ^ 0x800 * sub_weight
        #assert sub.suboctad == nsub
        assert sign == signed_o.sign == (-1)**o_signbit
        coc = mat24.suboctad_to_cocode(nsub, o.gcode)
        assert cocode == coc
        assert Cocode(sub) == Cocode(coc)
        assert sub == SubOctad(sub.sign * o, Cocode(coc))
        assert sub == sub.sign * SubOctad(no, Cocode(coc))

        o2 = Octad(randint(0, 758))
        sub2 = SubOctad(o, o2)
        assert Cocode(sub2) == Cocode(o & o2)
        assert len(Cocode(sub2)) // 2 & 1 == int((o & o2) / 2)

        t_sign, t_tag, t_i0, t_i1 = sub.vector_tuple()
        assert t_tag == 'T'
        assert t_sign == sign, (hex(sub.value), t_sign, o_signbit)
        assert t_i0 == no
        assert t_i1 == nsub
Esempio n. 4
0
class Perm64_xy(MM_Op):
    """Yet to be documented!!!!!!!!!!!!!!!!!!!!!

    """
    weights = sum(mat24.suboctad_weight(j) << j for j in range(64))
    mask = (1 << 64) - 1
    hi_list = [0, mask, weights, weights ^ mask]
    directives = {}

    def __init__(self, p):
        """Initialise for calulations with small integers modulo p

        p+1 must be a power of two. Calculations modulo p are described 
        in more detail in the base classes of this class.
        """
        super(Perm64_xy, self).__init__(p)
        self.t_hi = self.hi_table()
        self.t_lo = self.lo_table()
        self.tables.update(self.make_tables())

    def table_value(self, index):
        i0 = index & 0x3f
        v = sum(mat24.suboctad_scalar_prod(j, i0) << j for j in range(64))
        return self.hi_list[(index >> 6) & 3] ^ v

    def table_part(self, index):
        tbl = self.table_value(index)
        p, i_fields = self.P, self.INT_FIELDS
        return [self.smask(p, tbl >> i) for i in range(0, 64, i_fields)]

    def hi_table(self):
        return sum((self.table_part(i) for i in range(0, 256, 16)), [])

    def lo_table(self):
        return sum((self.table_part(i) for i in range(16)), [])

    def make_tables(self):
        return {
            "TABLE_PERM64_XY_LOW": self.t_lo,
            "TABLE_PERM64_XY_HIGH": self.t_hi,
        }
Esempio n. 5
0
def op_xy(v, eps, e, f):
    """Multiply unit vector v with group element

    This function multplies a (multiple of a) unit vector v
    with the group element

        g  =  d_<eps> * (x_<e>)**(-1)  * (y_<f>)**(-1) .
   
    It returns the vector w = v * g. This function uses the same 
    formula for calculating  w = v * g,  which is used in the 
    implementation of the monster group for computing
    v = w * g ** (-1).

    Input vector v  must be given as a tuple as described in class
    mmgroup.structures.abstract_mm_rep_space.AbstractMmRepSpace.
    Output vector is returned as a tuple of the same shape.
    """
    if len(v) == 3:
        v = (1,) + v
    v_value, v_tag, v_d, v_j = v
    parity = (eps >> 11) & 1  # parity of eps
    if v_tag == 'X':
        w_d = v_d ^ (f & 0x7ff)
        sign = v_d >> 12
        d = v_d & 0x7ff
        c =  m24.vect_to_cocode(1 << v_j)
        sign +=  m24.gcode_weight(e ^ f) 
        sign += m24.gcode_weight(f) 
        sign += m24.gcode_weight(d) * (parity + 1)
        sign += m24.gcode_weight(d ^ e ^ f)
        sign += m24.scalar_prod(e, c)
        cc = c if parity else 0 
        cc ^= eps ^ m24.ploop_theta(f) ^ m24.ploop_cap(e, f) 
        sign += m24.scalar_prod(d, cc)
        sign += f >> 12
        return (-1)**sign * v_value, 'X', w_d, v_j
    elif v_tag in 'YZ':
        tau = v_tag == 'Y'
        sigma = (tau + parity) & 1
        w_tag = "ZY"[sigma]
        sign = (v_d >> 12) + ((v_d >> 11) & tau)
        w_d = (v_d ^ e ^ (f & ~-sigma)) & 0x7ff
        #print("YZ, w_d", hex(w_d), hex(v_d ^ (e & 0x7ff) ^ (f & sigma_1)), err)
        # Next we check the sign
        d = v_d & 0x7ff
        c =  m24.vect_to_cocode(1 << v_j)
        sign += m24.ploop_cocycle(f, e) * (sigma + 1)
        sign += m24.gcode_weight(f) * (sigma)
        sign += m24.gcode_weight(d ^ e)  
        sign += m24.gcode_weight(d ^ e ^ f)  
        sign += m24.scalar_prod(f, c)
        cc = eps ^ m24.ploop_theta(e) 
        cc ^=  m24.ploop_theta(f) * ((sigma ^ 1) & 1)
        sign += m24.scalar_prod(d, cc)
        sign += (e >> 12) + (f >> 12) * (sigma + 1)
        sign += ((e >> 11) & sigma)
        return (-1)**sign * v_value, w_tag, w_d, v_j
    elif v_tag == 'T':
        d = m24.octad_to_gcode(v_d)
        w_j = v_j  ^ as_suboctad(f, d)
        sign = m24.gcode_weight(d ^ e) + m24.gcode_weight(e)
        sign +=  m24.scalar_prod(d, eps)
        sign += m24.suboctad_scalar_prod(as_suboctad(e ^ f, d), v_j)
        sign += m24.suboctad_weight(v_j) * parity
        return (-1)**sign * v_value, 'T', v_d, w_j
    elif v_tag in 'BC':
        m = v_tag == 'C'
        c = m24.vect_to_cocode((1 << v_d) ^ (1 << v_j))
        n = m ^ m24.scalar_prod(f, c)
        w_tag = "BC"[n]
        w_i, w_j = max(v_d, v_j), min(v_d, v_j)
        sign = m * parity + m24.scalar_prod(e ^ f, c)
        return (-1)**sign * v_value, w_tag, w_i, v_j
    elif v_tag == 'A':
        w_i, w_j = max(v_d, v_j), min(v_d, v_j)
        c = m24.vect_to_cocode((1 << v_d) ^ (1 << v_j))
        sign = m24.scalar_prod(f, c)
        return (-1)**sign * v_value,'A', w_i, v_j
    else:
        raise ValueError("Bad tag " + v_tag)