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)
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))
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()
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()
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)
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()
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
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()
def parity(self): return mat24.bw24(self.value) & 1
def __len__(self): return mat24.bw24(self.value)