Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
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. 4
0
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)
Esempio n. 5
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. 6
0
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