def mul_Tx(tag, octad, sub, g): d = m24.octad_to_gcode(octad) c = m24.suboctad_to_cocode(sub, d) e = g.pl s = m24.ploop_comm(d, e) s ^= m24.scalar_prod(e, c) return s, tag, octad, sub
def mul_Ty(tag, octad, sub, g): d = m24.octad_to_gcode(octad) c = m24.suboctad_to_cocode(sub, d) e = g.pl c1 = m24.ploop_cap(d, e) ^ c sub1 = m24.cocode_to_suboctad(c1, d) s = m24.scalar_prod(e, c) return s, tag, octad, sub1
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
def suboctad_to_cocode(suboctad, oct): """Compute code vector from octad and suboctad The octad 'oct' must be given in 'octad' representation and the suboctad must be given as in function mat24_suboctad_to_cocode in module mat24_functions.c. The function returns the suboctad as a cocode element in 'cocode' representation. """ gcode = mat24.octad_to_gcode(oct) return mat24.suboctad_to_cocode(suboctad, gcode)
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
def SubOctad(octad, suboctad=0): """Creates a suboctad as instance of class |XLeech2| :param octad: The first component of the pair *(octad, suboctad)* to be created. :type octad: same as in function :py:class:`~mmgroup.Octad` :param suboctad: The second component of the pair *(octad, suboctad)* to be created. :type suboctad: see table below for legal types :return: The suboctad given by the pair *(octad, suboctad)* :rtype: an instance of class |XLeech2| :raise: * TypeError if one of the arguments *octad* or *suboctad* is not of correct type. * ValueError if argument *octad* or *suboctad* does not evaluate to an octad or to a correct suboctad, respectively. A *suboctad* is an even cocode element that can be represented as a subset of the octad given by the argument *octad*. The raison d'etre of function ``SubOctad`` is that pairs *(octad, suboctad)* are used for indexing vectors in the representation of the monster group. Here we want to number the octads from ``0`` to ``758`` and the suboctads form ``0`` to ``63``, depending on the octad. Note that every octad has ``64`` suboctads. Depending on its type parameter **suboctad** is interpreted as follows: .. table:: Legal types for parameter ``suboctad`` :widths: 20 80 ===================== ================================================ type Evaluates to ===================== ================================================ ``int`` Here the suboctad with the number given in the argument is taken. That numbering depends on the octad given in the argument ``octad``. ``0 <= suboctad < 64`` must hold. ``list`` of ``int`` Such a list is converted to a bit vector as in class |GcVector|, and the cocode element corresponding to that bit vector is taken. class |GCode| The intersection of the octad given as the first argument and the Golay code word given as the second argument is taken. class |GcVector| This is converted to a cocode element, see class |Cocode|, and that cocode element is taken. class |Cocode| That cocode element is taken as the suboctad. ``str`` Create random element depending on the string | ``'r'``: Create arbitrary suboctad ===================== ================================================ The numbering of the suboctads Suboctads are numbered for 0 to 63. Let ``[b0, b1,..., b7]`` be the bits set in the octad of the pair ``(octad, suboctad)`` in natural order. The following table shows the suboctad numbers for some suboctads given as cocode elements. More suboctad numbers can be obtained by combining suboctads and their corresponding numbers with ``XOR``. .. table:: Suboctad numbers of some cocode elements :widths: 16 16 16 16 18 18 =========== =========== =========== =========== =========== =========== ``[b0,b1]`` ``[b0,b2]`` ``[b0,b3]`` ``[b0,b4]`` ``[b0,b5]`` ``[b0,b6]`` ``s = 1`` ``s = 2`` ``s = 4`` ``s = 8`` ``s = 16`` ``s = 32`` =========== =========== =========== =========== =========== =========== E.g. ``[b0, b5, b6, b7]`` is equivalent to ``[b1, b2, b3, b4]`` modulo the Golay code and has number ``s = 1 ^ 2 ^ 4 ^ 8 = 15``. """ ploop = Octad(octad) gcode = ploop.value & 0xfff if isinstance(suboctad, str): suboctad_ = randint(0, 63) elif isinstance(suboctad, Integral): suboctad_ = suboctad & 0x3f elif isinstance(suboctad, GCode): value = mat24.ploop_cap(gcode, suboctad.value) suboctad_ = mat24.cocode_to_suboctad(value, gcode) else: value = Cocode(suboctad).cocode suboctad_ = mat24.cocode_to_suboctad(value, gcode) cocode = mat24.suboctad_to_cocode(suboctad_, gcode) if import_pending: complete_import() result = XLeech2(ploop, cocode) subtype = result.xsubtype assert subtype in [0x22, 0x42], (hex(subtype), hex(ploop), hex(cocode), hex(result.value)) # complent a complement of an octad if subtype == 0x42: result.value ^= 0x800000 return result