示例#1
0
def ref_gen_leech2_reduce_n(v, verbose=0):
    vtype = gen_leech2_subtype(v)
    subtype = vtype & 0xf

    out = []

    if subtype & 1:
        coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff
        syn = mat24.cocode_syndrome(coc)
        src = mat24.vect_to_list(syn, mat24.bw24(syn))
        assert len(src) in [1, 3]
        lst = [1, 2, 3] if subtype == 3 else [0]
        apply_perm(v, src, lst, len(src), out)
        v = gen_leech2_op_atom(v, out[0])
        out.append(0xC0000000 + ((v >> 12) & 0x7ff))
        v = gen_leech2_op_atom(v, out[1])
        out.append(0xB0000000 + ((v >> 13) & 0x800))
    elif subtype == 6:
        gv = (v >> 12) & 0xfff
        vect = mat24.gcode_to_vect(gv)
        src = mat24.vect_to_list(vect, mat24.bw24(vect))
        assert len(src) == 12
        dest = STD_DODECAD
        if (vtype == 0x36):
            coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff
            w = mat24.bw24(mat24.cocode_as_subdodecad(coc, gv))
            if w & 2:
                dest = CPL_DODECAD
        pi = mat24.perm_from_dodecads(dest, src)
        out.append(0xA0000000 + mat24.perm_to_m24num(pi))
        op_y_x(v, TABLE_DODECAD, out)
    elif subtype in [2, 4]:
        if vtype == 0x34:
            find_octad_permutation_odd(v, out)
        else:
            find_octad_permutation(v, out)
        op_y_x(v, TABLE_OCTAD, out)
    elif subtype in [0, 8]:
        if ((v & 0x7ff) == 0):
            out.append(0xA0000000)
            out.append(0xC0000000)
            x = 0x800 if v & 0x1800000 == 0x1800000 else 0
            out.append(0x90000000 + x)
        else:
            syn = mat24.cocode_syndrome(v & 0x7ff, 0)
            src = mat24.vect_to_list(syn, mat24.bw24(syn))
            j = mat24.bw24(syn) & 2
            lst, y0 = ([2, 3], 0x200) if j else ([0, 1, 2, 3], 0x400)
            apply_perm(v, src, lst, len(lst), out)
            v = gen_leech2_op_atom(v, out[0])
            y = y0 if v & 0x800000 else 0
            out.append(0xC0000000 + y)
            v = gen_leech2_op_atom(v, out[1])
            x = y0 if v & 0x1000000 else 0
            out.append(0xB0000000 + x)
    else:
        raise ValueError("Bad subtype " + hex(vtype))
    assert len(out) == 3
    return vtype, np.array(out, dtype=np.uint32)
示例#2
0
def sort_single_size3_block(A):
    """Sort entries of matrix with single 3 times 3 block

    If matrix ``A`` contains a single 3 times 3 block and some
    diagonal entries the the function returns a permutation that 
    moves the 3 times 3 block to rows and columns 0, 1, and 2.
    That permutation is returned as an instance of class ``MM0``.
    
    Otherwise the function returns the neutral element in
    class ``MM0``.
    """
    bl = blocks(A)
    if mat24.bw24(bl[0]) != 3 or mat24.bw24(bl[1]) != 1:
        return MM0()
    blist = [x for x in range(24) if bl[0] & (1 << x)]
    dlist = sorted([(-A[x, x], x) for x in blist])
    src = [x[1] for x in dlist]
    return MM0('p', AutPL(0, zip(src, [0, 1, 2]), 0))
示例#3
0
def beautify_block_size3(A):
    """Try to order a matrix with a 3 times 3 block

    If matrix ``A`` has a 3 times 3 block in rows 0, 1, and 2, then
    the function checks the diagonal entries with index >= 3. It 
    looks for a set of equal diagonal entries such that the union
    of the indices of these entries with the set [1,2,3] is an octad.
    If this is the case then the function returns an element ``g`` 
    that that moves this octad to the first 8 rows and columns.

    In case of success that element is returned as an instance of 
    class ``MM0``. Otherwise the neutral element in class ``MM0``
    is returned.    
    """
    bl = blocks(A)
    if mat24.bw24(bl[0]) != 3:
        return MM0()
    blist = [x for x in range(24) if bl[0] & (1 << x)]
    if (blist != [0, 1, 2]):
        return MM0()
    d = defaultdict(list)
    for b in bl:
        if b & (b - 1) == 0:
            index = b.bit_length() - 1
            d[A[index, index]].append(index)
    for lst in d.values():
        if len(lst) < 8:
            try:
                gc = GCode(blist + lst).bit_list
                assert len(gc) == 8
            except:
                continue
            isect = set(blist) & set(gc)
            #print("isect", isect)
            if len(isect) == 3:
                src0 = [x for x in gc if x in isect]
                src1 = [x for x in gc if not x in isect]
                dest = range(6)
                pi = AutPL(0, zip(src0 + src1[:3], dest), 0)
                return MM0(pi)
            if len(isect) == 1:
                src = gc
                dest = list(range(8))
                src0 = [x for x in gc if not x in isect]
                src1 = [x for x in gc if x in isect]
                src2 = [x for x in blist if x not in src1]
                dest = list(range(10))
                for i in range(1000):
                    shuffle(src0)
                    shuffle(src2)
                    try:
                        pi = AutPL(0, zip(src0 + src1 + src2, dest))
                        return MM0(pi)
                    except:
                        pass
    return MM0()
示例#4
0
def beautify_block_size2(A):
    """Try to order a matrix with 2 times 2 block

    If matrix ``A`` has  2 times 2 blocks then the function checks 
    the diagonal entries. It looks for a set of equal diagonal entries 
    such that the union of the indices an octad (up to a syndrome of
    length at most 3).
    If this is the case then the function returns an element ``g`` 
    that that moves this octad to the first 8 rows and columns.

    In case of success that element is returned as an instance of 
    class ``MM0``. Otherwise the neutral element in class ``MM0``
    is returned.    
    """
    bl = blocks(A)
    if mat24.bw24(bl[0]) != 2:
        return MM0()
    blist = [x for x in range(24) if bl[0] & (1 << x)]
    d = defaultdict(list)
    for b in bl:
        if b & (b - 1) == 0:
            index = b.bit_length() - 1
            d[A[index, index]].append(index)
    for lst in d.values():
        if len(lst) <= 8:
            try:
                #print(lst)
                gc = GCode(blist + lst).bit_list
                #print("GC =", gc)
            except:
                continue
            if set(blist).issubset(gc) and len(gc) == 8:
                src0 = [x for x in gc if x in blist]
                src1 = [x for x in gc if x not in blist]
                dest = list(range(8))
                for i in range(1000):
                    shuffle(src1)
                    try:
                        pi = AutPL(0, zip(src0 + src1, dest), 0)
                        return MM0(pi)
                    except:
                        pass
            if len(set(blist) & set(gc)) == 0 and len(gc) == 8:
                src0 = gc
                src1 = blist
                dest = list(range(10))
                for i in range(10000):
                    shuffle(src0)
                    try:
                        pi = AutPL(0, zip(src0 + src1, dest), 0)
                        return MM0(pi)
                    except:
                        pass
    return MM0()
示例#5
0
 def __init__(self, value):
     if import_pending:
         complete_import()
     if isinstance(value, Integral):
         self.value = value & 0xffffff
     elif isinstance(value, GCode):
         self.value = mat24.gcode_to_vect(value.value)
     elif isinstance(value, GcVector):
         self.value = value.value
     elif isinstance(value, PLoopIntersection):
         self.value = (mat24.gcode_to_vect(value.v1)
                       & mat24.gcode_to_vect(value.v2) & 0xffffff)
     elif isinstance(value, str):
         self.value = randint(0, 0xffffff)
         if 'e' in value and not 'o' in value:
             if mat24.bw24(self.value) & 1:
                 self.value ^= 1 << randint(0, 23)
         if 'o' in value and not 'e' in value:
             if not mat24.bw24(self.value) & 1:
                 self.value ^= 1 << randint(0, 23)
     else:
         self.value = as_vector24(value)
示例#6
0
def beautify_diagonal_matrix(A):
    """Try to order a diagonal matrix

    If matrix ``A`` is diagonal then the function looks for a set 
    of equal diagonal entries that is close to an octad or to a
    dodecad.  If this is the case then the function returns an 
    element ``g`` that that moves this Golay code word to a
    standard position.

    In case of success that element is returned as an instance of 
    class ``MM0``. Otherwise the neutral element in class ``MM0``
    is returned.    
    """
    bl = blocks(A)
    if mat24.bw24(bl[0]) != 1:
        return MM0()
    d = defaultdict(list)
    for b in bl:
        if b & (b - 1) == 0:
            index = b.bit_length() - 1
            d[A[index, index]].append(index)
    singleton = None
    for lst in d.values():
        if len(lst) == 1: singleton = lst
    for lst in d.values():
        dest = list(range(8))
        if len(lst) == 8:
            #print(lst)
            for i in range(10000):
                shuffle(lst)
                try:
                    pi = AutPL(0, zip(lst, dest), 0)
                    #print("yeah")
                    return MM0(pi)
                except:
                    continue
        elif len(lst) == 11 and singleton:
            print("dodecad")
            DOD = 0xeee111
            dest = [i for i in range(24) if (1 << i) & DOD]
            src = singleton + lst
            #print(dest)
            #print(src)
            #return MM0()
            pi = mat24.perm_from_dodecads(src, dest)
            return MM0('p', pi)
        elif singleton:
            pi = pi = AutPL(0, zip(singleton, [0]), 0)
            return MM0('p', pi)
    return MM0()
示例#7
0
 def __truediv__(self, other):
     if isinstance(other, Integral):
         other = abs(other)
         if other == 1:
             return self
         w = mat24.bw24(self.value)
         if other == 2 and w & 1 == 0:
             return Parity(w >> 1)
         elif other == 4 and w & 3 == 0:
             return Parity(w >> 2)
         elif other in (2, 4):
             err = "Don't know weight of Omega vector / %d"
             raise ValueError(err % other)
         else:
             raise TypeError(ERR_DIV4 % self.__class__)
     else:
         return NotImplemented
示例#8
0
def beautify_signs_size2_3(A):
    """Adjust sign of matrix with 2 times 2 and 3 times 3 blocks

    If matrix ``A`` contains 2 times 2 blocks, 3 times 3 blocks 
    and some  diagonal entries then the function returns an element 
    of the  monster that changes all off-diagonal signs to 
    reaonable values. 
    That element is returned as an instance of class ``MM0``.
    
    Otherwise the function returns the neutral element in
    class ``MM0``.
    """
    bl = blocks(A)
    if not 2 <= mat24.bw24(bl[0]) <= 3:
        return MM0()
    lplus3, lminus3, l2 = [], [], []
    for b in bl:
        blist = [x for x in range(24) if b & (1 << x)]
        if len(blist) == 2:
            i0, i1 = blist
            l2.append((i0, i1))
        if len(blist) == 3:
            i0, i1, i2 = blist
            sign = A[i0, i1] * A[i0, i2] * A[i1, i2]
            ls = lminus3 if sign < 0 else lplus3
            l = [(i0, i1), (i0, i2), (i1, i2)]
            ls += l
    try:
        y = change_signs_A(A, lplus3 + l2, lminus3)
        return MM0('y', y)
    except ValueError:
        try:
            y = change_signs_A(A, lplus3, lminus3 + l2)
            return MM0('y', y)
        except ValueError:
            try:
                y = change_signs_A(A, l2)
                return MM0('y', y)
            except ValueError:
                try:
                    y = change_signs_A(A, [], l2)
                    return MM0('y', y)
                except ValueError:
                    # No improvement found
                    return MM0()
示例#9
0
 def parity(self):
     return mat24.bw24(self.value) & 1
示例#10
0
 def __len__(self):
     return mat24.bw24(self.value)