def cocode(i, gc_ref): syn0 = 0 if gc_ref: gc_list = gc(gc_ref) if len(gc_list): syn0 = gc_list[0] c = Cocode(i) return c.syndrome_list(syn0)
def subtype_testdata(): yield XLeech2(~PLoop()) yield XLeech2(Cocode([0, 1, 2, 3])) yield XLeech2(~PLoop(list(range(8)))) yield XLeech2(~PLoop(list(range(8))), Cocode([8, 9])) for i in range(50): yield XLeech2('r', 4)
def test_parity(): odd, even = Parity(3), Parity(-4) assert odd != even assert Parity(-311) == odd assert int(odd) == 1 assert int(even) == 0 assert (-1)**odd == -1 assert (-1)**even == 1 assert 1**odd == 1**even == 1 assert odd + 1 == odd - 1 == 1 + odd == odd + odd == 7 - odd == even assert odd * odd == -odd == odd assert odd * even == even * odd == 2 * odd == even * 3 == even print("\nPossible parities are:", odd, ",", even) with pytest.raises(ValueError): 2**even with pytest.raises(TypeError): even & even cc1, cc0 = Cocode(0x823), Cocode(0x7ef) assert cc1 + even == even + cc1 == cc0 + odd == odd + cc0 == odd assert cc1 + odd == odd + cc1 == cc0 + even == even + cc0 == even assert odd * cc1 == cc1 * odd == cc1 ccn = Cocode(0) assert even * cc1 == cc1 * even == even * cc0 == cc0 * even == ccn pl = PLoop(0x1234) gc = GCode(pl) assert even * pl == even * gc == GCode(0) assert odd * pl == odd * gc == gc aut = AutPL('e', 'r') assert odd * aut == odd assert even * aut == even
def test_create_group_permutation(): for i, (src, dest, num) in enumerate(create_perm_testvectors()): p1 = AutPL(0, zip(src, dest)) p1.check() p1c = p1.copy().check() assert p1c == p1 assert p1.perm_num == num assert p1 == AutPL(0, dict(zip(src, dest))).check() assert p1 == AutPL(0, num).check() assert p1 == AutPL(p1).check() assert p1.cocode == 0 perm = p1.perm assert isinstance(perm, list) assert min(perm) == 0 and max(perm) == 23 for x, y in zip(src, dest): assert perm[x] == y assert p1 == AutPL(0, perm) coc = Cocode(randint(1, 0xfff)) p2 = AutPL(coc, 0) * AutPL(0, perm) p2.check() assert p2 == (AutPL(coc) * AutPL(0, perm)).check() assert p2 == AutPL(coc, perm).check() assert p2 != p1 assert p2.perm_num == p1.perm_num assert p2.cocode == coc.cocode p2c = AutPL(0, perm) * AutPL(coc, 0).check() assert p2.perm_num == p1.perm_num assert Cocode(p2c.cocode) * p2 == coc assert p2 == AutPL(Cocode(p2.cocode), 0) * AutPL(0, p2.perm)
def eval_a_testdata(): data = [ (V("A", 2, 2), Cocode([2, 3]).ord, 0), ] for d in data: yield d for i0 in range(24): for i1 in range(i0): yield V('R'), Cocode([i0, i1]).ord, 0 for k in range(100): yield V('R'), rand_leech2(), 0 for e in (1, 2): for k in range(100): yield V('R'), rand_leech2(), e
def calc_conjugate_to_opp(i0, i1): coc = Cocode([i0, i1]) g = G('d', coc) v = V15('I', i0, i1) coc_value = coc.ord x = PLoop(coc_value & -coc_value) return G('x', x)
def display_leech_vector(x): """Display a vector in the Leech lattice mod 2 Here parameter ``x`` is a vector in the Leech lattice mod 2 in Leech lattice encoding. """ gcode = PLoop(x >> 12) bl = gcode.bit_list print("GCode:\n", bl) if len(bl) == 16: l = [x for x in range(24) if not x in bl] pos = bl[0] elif len(gcode): pos = bl[0] else: pos = 0 cocode = Cocode(x) + gcode.theta() print("Cocode:", cocode.syndrome_list(pos))
def xs_vector(ploop, cocode): """Convert entry of table TYPE_DATA to a Leech lattice vector Calling ``xs_vector(ploop, cocode)``, where ``ploop`` and ``cocode`` are taken from an entry of the list TYPE_DATA, returns the vector in the Leech lattice mod 2 corresponding to that entry in Leech lattice encoding. """ return Xsp2_Co1([("x", ploop), ("d", Cocode(cocode))]).as_xsp()
def test_group_from_perm(n_cases): for i in range(n_cases): h1 = rand_u7() h2 = rand_u7() autp = AutPL(0, zip(h1, h2)) assert autp == AutPL(0, dict(zip(h1, h2))) assert autp.perm == mat24.perm_from_heptads(h1, h2) assert autp.cocode == 0 perm_num = autp.perm_num assert perm_num == mat24.perm_to_m24num(autp.perm) assert autp == AutPL(0, mat24.perm_from_heptads(h1, h2)) assert autp == AutPL(autp) assert autp == AutPL(0, autp.perm_num) assert autp == AutPL(0, zip(h1, h2)) coc_num = randint(1, 0xfff) coc = Cocode(coc_num) assert coc != Cocode(0) assert coc.cocode == coc_num im_coc = coc * autp assert type(im_coc) == type(coc) assert AutPL(im_coc) == AutPL(coc)**autp aut_cp = AutPL(coc) * autp assert aut_cp == AutPL(coc_num, perm_num) if coc_num and perm_num: assert aut_cp.as_tuples() == [('d', coc_num), ('p', perm_num)] assert autp * AutPL(im_coc) == aut_cp assert type(aut_cp) == type(autp) assert aut_cp.perm_num == perm_num assert aut_cp.cocode == coc_num assert Parity(aut_cp) == Parity(coc) assert aut_cp.parity == coc.parity == Parity(coc).ord assert autp == AutPL() * autp == autp * AutPL() with pytest.raises(TypeError): autp * coc with pytest.raises(TypeError): autp * Parity(randint(0, 9)) with pytest.raises(TypeError): autp * randint(2, 9) with pytest.raises(TypeError): randint(2, 9) * autp with pytest.raises(TypeError): autp * PLoop(randint(0, 0x1fff))
def test_ABC(n_cases): for p in characteristics(): sp = space(p) for _ in range(n_cases): i1 = i0 = randint(0, 23) while i1 == i0: i1 = randint(0, 23) scalar = randint(1, p-1) + p * randint(-5, 5) for tag in "ABC": c0 = Cocode([i0]) c1 = Cocode([i1]) v0 = GcVector([i0]) v1 = GcVector([i1]) ref = sp(tag, i0, i1) for j0 in [i0, c0, v0]: for j1 in [i1, c1, v1]: assert sp(tag, j0, j1) == ref mmv = sp() mmv[tag, j0, j1] = scalar assert mmv == scalar * ref assert mmv[tag, j0, j1] == scalar % p
def test_cocode(): print("") for i in range(200): # Test power map, inveriosn, sign, theta, and conversion to GCode n1 = randint(0, 0x1fff) p1 = PLoop(n1) ccvector = randint(0, 0xffffff) coc = mat24.vect_to_cocode(ccvector) cclist = [i for i in range(24) if (ccvector >> i) & 1] cc1 = Cocode(cclist) cc2 = Cocode(coc) if i < 1: print("\nTesting", GcVector(ccvector), ", cocode =", cc1) assert cc1 == cc2 u = Parity(mat24.scalar_prod(p1.value, cc1.value)) assert p1 & cc1 == u == cc1 & p1 == u * 1 == u + 0 par = Parity(randint(0, 1)) assert cc1 + par == par + cc1 == cc1.value // 0x800 + par assert cc1 % 2 == Parity(cc1) assert len(cc1) == mat24.cocode_weight(cc1.value) if len(cc1) < 4: syndrome = mat24.cocode_syndrome(cc1.value) assert cc1.syndrome().value == syndrome syn_from_list = sum(1 << i for i in GcVector(ccvector).syndrome_list()) assert syn_from_list == syndrome i = randint(0, 23) assert cc1.syndrome(i).value == mat24.cocode_syndrome(cc1.value, i) syndrome_list = cc1.syndrome(i).bit_list assert len(cc1) == len(syndrome_list) assert syndrome_list == mat24.cocode_to_bit_list(cc1.value, i)
def test_T(n_cases): for p in characteristics(): sp = space(p) for _ in range(n_cases): o = randint(0, 758) so = randint(0, 63) coc = Cocode(SubOctad(o, so)) v = GcVector (coc.syndrome(randint(0,23))) sgn = randint(0, 1) pl = PLoopZ(sgn) * Octad(o) gc = GCode(pl) scalar = randint(1, p-1) + p * randint(-5, 5) assert gc == GCode(pl) ref = (-1)**sgn * sp('T', o, so) for sign, d in ((sgn,o), (sgn,gc), (0, pl)): for par2 in (so, coc, v): assert (-1)**sign * sp('T', d, par2) == ref mmv = sp() mmv['T', d, par2] = (-1)**sign * scalar assert mmv == scalar * ref signed_scalar = (-1)**sign * scalar % p assert mmv['T', d, par2] == signed_scalar
def solve_gcode_diag(l): """Solve cocode equation Here ``l`` is a list of tupeles ``(i0, i1, k)``. For an unknown Golay code word ``x``, each tuple means an equation ``<x, Cocode([i0,i1])> = k``, where ``<.,.>`` is the scalar product. If a solution ``x`` exists then the function returns ``x`` as an instance of class |PLoop|. """ a = np.zeros(len(l), dtype=np.uint64) for i, (i0, i1, k) in enumerate(l): a[i] = Cocode([i0, i1]).ord + ((int(k) & 1) << 12) v = bitmatrix64_solve_equation(a, len(l), 12) if v < 0: err = "Off-diagonal matrix equation has no solution" raise ValueError(err) result = PLoop(v) for i0, i1, k in l: c = Cocode([i0, i1]) check = hex(result.ord), hex(c.ord), k assert result & c == Parity(int(k)), check return result
def test_group_op(n_cases=100): print("") for i in range(n_cases): p1 = AutPL('r', 'r') p2 = rand_autpl_u7() p2 *= AutPL(Cocode(randint(0, 0xfff))) p12 = (p1 * p2).check() assert p12.rep == mat24.mul_autpl(p1.rep, p2.rep) if i < 1: print(p1, "*", p2, "=", p12) p3 = AutPL('r', 'r') assert (p1 * p2) * p3 == p1 * (p2 * p3) p1i = (p1**-1).check() assert p1 * p1i == p1i * p1 == AutPL()
def test_autploop(n_cases): for i in range(n_cases): autp = AutPL('r', 'r') g = group(autp) assert g == group([('d', autp.cocode), ('p', autp.perm)]) assert g == group('p', autp) coc, p_num = autp.cocode, autp.perm_num if coc and p_num: assert g.as_tuples() == autp.as_tuples() assert g.as_tuples() == [('d', coc), ('p', p_num)] Coc = Cocode(coc) h1 = range(9, 18) h2 = autp.perm[9:18] assert g == group([('d', Coc), ('p', zip(h1, h2))]) assert g == group([('d', Coc), ('p', dict(zip(h1, h2)))])
def map_cooctad(i): """Return a certain perumtation in the Mathieu group M_24 The function returns a permutation in the Mathieu group ``M_24`` that fixes the octad (0,1,...,7) as a set, and the element 8, and that maps i to 9. The permutation is returned as an instance of class AutPL """ if not 9 <= i < 24: raise ValueError("Bad paramter for function map_octad()") if i == 9: return AutPL(0) s0 = [0] + Cocode([0, 8, 9, i, i ^ 1]).syndrome_list() s1 = [x for x in range(8) if not x in s0] src = s0 + s1[:1] + [8, i] dest = [0, 1, 2, 3, 4, 8, 9] return AutPL(0, zip(src, dest), 0)
def iter_d(tag, d): if isinstance(d, Integral): yield 0x10000000 + (d & 0xfff) elif isinstance(d, str): cocode = randint(d == 'n', 0xfff) if d == "o": cocode |= 1 elif d == "e": cocode &= ~1 if len(d) == 1 and d in "rnoe": yield 0x10000000 + (cocode & 0xfff) else: raise ValueError(ERR_ATOM_VALUE % 'd') else: try: cocode = Cocode(d).cocode yield 0x10000000 + (cocode & 0xfff) except: raise TypeError(ERR_ATOM_TYPE % (type(d), 'd'))
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 test_group_ploop(n_cases): print("") for i, (c, v, g) in enumerate( zip(cocode_testvectors(n_cases), get_testvectors(n_cases), autpl_testwords(n_cases))): cg = c * g vg = v * g if i < 1: print(c, "*", g, "=", cg) print(v, "*", g, "=", vg) cg_ref = Cocode(mat24.op_cocode_perm(c.ord, g.perm)) assert cg == cg_ref assert len(cg) == len(c) vg_ref = GcVector(mat24.op_vect_perm(v.ord, g.perm)) assert vg == vg_ref assert len(vg) == len(v) if len(v) & 1 == 0: assert v / 2 == vg / 2 == Parity(len(v) >> 1) if len(v) & 3 == 0: assert v / 4 == vg / 4 == Parity(len(v) >> 2) assert v % 2 == vg % 2 == Parity(len(v))
def perm_mapping(length): """Create a mapping defining a unique permutation p in Mat24. Return a triple (src, dest, perm_num) with src, dest being lists of the given 'length' satisfying: p[src[i]] = dest[i] for 0 <= i < length . for a unique permutation p in Mat24. p has the internal number perm_num. 7 <= length < 24 must hold. The function does not use any internal numbering or random process of the mmgroup package for creating the permutation p. """ p = rand_autpl_u7() # p is a random permutation in AutPL perm = p.perm assert length >= 7 while True: src = sample(range(24), length) if length >= 9 or len(Cocode(src)) >= 2: # The the permutation is determined by its effect on src return src, [perm[i] for i in src], p.perm_num
def test_AD(n_cases): for p in characteristics(): sp = space(p) for _ in range(n_cases): i0 = randint(0, 23) scalar = randint(1, p-1) + p * randint(-5, 5) c0 = Cocode([i0]) v0 = GcVector([i0]) ref = sp('A', i0, i0) for j0 in [i0, c0, v0]: for j1 in [i0, c0, v0]: assert sp('A', j0, j1) == ref mmv = sp() mmv['A', j0, j1] = scalar assert mmv == scalar * ref assert mmv['A', j0, j1] == scalar % p d1 = sp('D', j0) assert sp('D', j0) == ref mmv = sp() mmv['D', j0] = scalar assert mmv == scalar * ref assert mmv['D', j0] == scalar % p
def test_XYZ(n_cases): for p in characteristics(): sp = space(p) for _ in range(n_cases): d = randint(0, 0x1fff) i = randint(0, 23) c = Cocode([i]) v = GcVector([i]) pl = PLoop(d) gc = GCode(d & 0xfff) d0 = d & 0x7ff scalar = randint(1, p-1) + p * randint(-5, 5) for tag in "XYZ": s2 = s1 = d >> 12 if tag == "Y": s1 ^= d >> 11 ref = (-1)**s1 * sp(tag, d0, i) for sign, dd in ((s1, d0), (s2, gc), (0, pl)): for j in [i, c, v]: assert (-1)**sign * sp(tag, dd, j) == ref mmv = sp() mmv[tag, dd, j] = (-1)**sign * scalar assert mmv == scalar * ref signed_scalar = (-1)**sign * scalar % p assert mmv[tag, dd, j] == signed_scalar
from mmgroup import mat24 from mmgroup.generators import gen_leech2_type from mmgroup.generators import gen_leech2_subtype from mmgroup.generators import gen_leech2_op_atom from mmgroup.generators import gen_leech2_reduce_type4 from mmgroup.generators import gen_leech2_op_word from mmgroup.generators import gen_leech2_start_type4 from mmgroup.generators import gen_leech2_start_type24 # Standard vector in the Leech lattice mod 2 in Leech lattice encoding # The standard fram \Omega OMEGA = 0x800000 # The standard type-2 vector \beta BETA = 0x200 assert Cocode(BETA).syndrome() == GcVector(0xC) ##################################################################### # Test function gen_leech2_start_type4 ##################################################################### ##################################################################### # Reference implementation of gen_leech2_start_type4() def ref_leech2_start_type4(v): """Reference implementation for function gen_leech2_start_type4 This is equivalent to function ``leech2_start_type4```. """ v &= 0xffffff
def reduce_type2_ortho(v, verbose=0): r"""Map (orthgonal) short vector in Leech lattice to standard vector This is a python implementation of the C function ``gen_leech2_reduce_type2_ortho`` in file ``gen_leech.c``. Let ``v \in \Lambda / 2 \Lambda`` of type 2 be given by parameter ``v`` in Leech lattice encoding. In the real Leech lattice, (the origin of) the vector ``v`` must be orthogonal to the standard short vector ``beta``. Here ``beta`` is the short vector in the Leech lattice propotional to ``e_2 - e_3``, where ``e_i`` is the ``i``-th basis vector of ``\{0,1\}^{24}``. Let ``beta'`` be the short vector in the Leech lattice propotional to ``e_2 + e_3``. Then the function constructs a ``g \in G_{x0}`` that maps ``v`` to ``beta'`` and fixes ``beta``. The element ``g`` is returned as a word in the generators of ``G_{x0}`` of length ``n \leq 6``. Each atom of the word ``g`` is encoded as defined in the header file ``mmgroup_generators.h``. The function stores ``g`` as a word of generators in the array ``pg_out`` and returns the length ``n`` of that word. It returns a negative number in case of failure, e.g. if ``v`` is not of type 2, or not orthogonal to ``beta'`` in the real Leech lattice. """ vtype = gen_leech2_subtype(v) if (vtype >> 4) != 2: raise ValueError("Vector is not short") if gen_leech2_type(v ^ 0x200) != 4: raise ValueError("Vector not orthogonal to standard vector") result = [] for _i in range(4): if verbose: coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff vt = gen_leech2_subtype(v) coc_anchor = 0 if vt in [0x22]: w = mat24.gcode_weight(v >> 12) vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12) coc_anchor = mat24.lsbit24(vect) coc_syn = Cocode(coc).syndrome_list(coc_anchor) gcode = mat24.gcode_to_vect(v >> 12) print("Round %d, v = %s, subtype %s, gcode %s, cocode %s" % (_i, hex(v & 0xffffff), hex(vt), hex(gcode), coc_syn)) assert vtype == gen_leech2_subtype(v) if vtype == 0x21: exp = xi_reduce_odd_type2(v) vtype = 0x22 elif vtype == 0x22: exp = xi_reduce_octad(v) if exp < 0: w = mat24.gcode_weight(v >> 12) vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12) if vect & 0x0c: vect &= ~0x0c src = mat24.vect_to_list(vect, 2) + [2, 3] dest = [0, 1, 2, 3] else: src = [2, 3] + mat24.vect_to_list(vect, 3) v5 = (1 << src[2]) | (1 << src[3]) | (1 << src[4]) v5 |= 0x0c special = mat24.syndrome(v5, 24) src.append(mat24.lsbit24(special & vect)) dest = [2, 3, 4, 5, 6, 7] v = apply_perm(v, src, dest, len(src), result, verbose) exp = xi_reduce_octad(v) assert exp >= 0 vtype = 0x20 elif vtype == 0x20: if ((v & 0xffffff) == 0x800200): return np.array(result, dtype=np.uint32) syn = (mat24.cocode_syndrome(v, 0)) & ~0xc if syn and syn != 3: src = mat24.vect_to_list(syn, 2) + [2, 3] v = apply_perm(v, src, [0, 1, 2, 3], 4, result, verbose) exp = 2 - ((v >> 23) & 1) else: raise ValueError("WTF") if exp: exp = 0xE0000003 - exp v = gen_leech2_op_atom(v, exp) result.append(exp) raise ValueError("WTF1")
def reduce_type4_std(v, verbose=0): r"""Map type-4 vector in Leech lattice to standard vector This is (almost) a python implementation of the C function ``gen_leech2_reduce_type4`` in file ``gen_leech.c``. Let ``v \in \Lambda / 2 \Lambda`` of type 4 be given by parameter ``v`` in Leech lattice encoding. Let ``Omega`` be the type- vector in the Leech lattice corresponding to the standard coordinate frame in the Leech lattice. Then the function constructs a ``g \in G_{x0}`` that maps ``v`` to ``Omega``. The element ``g`` is returned as a word in the generators of ``G_{x0}`` of length ``n \leq 6``. Each atom of the word ``g`` is encoded as defined in the header file ``mmgroup_generators.h``. The function stores ``g`` as a word of generators in the array ``pg_out`` and returns the length ``n`` of that word. It returns a negative number in case of failure, e.g. if ``v`` is not of type 4. We remark that the C function ``gen_leech2_reduce_type4`` treats certain type-4 vectors ``v`` in a special way as indicated in function ``reduce_type4``. """ if verbose: print("Transforming type-4 vector %s to Omega" % hex(v & 0x1ffffff)) vtype = gen_leech2_subtype(v) result = [] for _i in range(5): coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff if verbose: vt = gen_leech2_subtype(v) coc_anchor = 0 if vt in [0x42, 0x44]: w = mat24.gcode_weight(v >> 12) vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12) coc_anchor = mat24.lsbit24(vect) coc_syn = Cocode(coc).syndrome_list(coc_anchor) gcode = mat24.gcode_to_vect(v >> 12) print("Round %d, v = %s, subtype %s, gcode %s, cocode %s" % (_i, hex(v & 0xffffff), hex(vt), hex(gcode), coc_syn)) assert vtype == gen_leech2_subtype(v) if vtype == 0x48: if verbose: res = list(map(hex, result)) print("Transformation is\n", res) return np.array(result, dtype=np.uint32) elif vtype == 0x40: if v & 0x7ffbff: syn = mat24.cocode_syndrome(coc, 0) src = mat24.vect_to_list(syn, 4) v = apply_perm(v, src, LSTD, 4, result, verbose) #print("after type 40", hex(v), Cocode(v).syndrome(0)) exp = 2 - ((v >> 23) & 1) vtype = 0x48 elif vtype in [0x42, 0x44]: exp = xi_reduce_octad(v) if exp < 0: v = find_octad_permutation(v, result, verbose) exp = xi_reduce_octad(v) assert exp >= 0 vtype = 0x40 elif vtype == 0x46: exp = xi_reduce_dodecad(v, verbose) if exp < 0: vect = mat24.gcode_to_vect(v >> 12) src = mat24.vect_to_list(vect, 4) v = apply_perm(v, src, LSTD, len(src), result, verbose) exp = xi_reduce_dodecad(v, verbose) assert exp >= 0 vtype = 0x44 elif vtype == 0x43: exp = xi_reduce_odd_type4(v, verbose) if exp < 0: vect = mat24.gcode_to_vect(v >> 12) syn = mat24.cocode_syndrome(coc, 24) src = mat24.vect_to_list(syn, 3) #print("coc list", src) v = apply_perm(v, src, LSTD[1:], len(src), result, verbose) exp = xi_reduce_odd_type4(v, verbose) assert exp > 0 vtype = 0x42 + ((exp & 0x100) >> 7) exp &= 3 else: raise ValueError("WTF") if exp: exp = 0xE0000003 - exp v_old = v v = gen_leech2_op_atom(v, exp) assert v & 0xfe000000 == 0, (hex(v_old), hex(exp), hex(v)) result.append(exp) raise ValueError("WTF1")
def reduce_type2(v, verbose=1): r"""Map (orthgonal) short vector in Leech lattice to standard vector This is a python implementation of the C function ``gen_leech2_reduce_type2`` in file ``gen_leech.c``. Let ``v \in \Lambda / 2 \Lambda`` of type 2 be given by parameter ``v`` in Leech lattice encoding. Let ``beta`` be the short vector in the Leech lattice propotional to ``e_2 - e_3``, where ``e_i`` is the ``i``-th basis vector of ``\{0,1\}^{24}``. Then the function constructs a ``g \in G_{x0}`` that maps ``v`` to ``beta``. The element ``g`` is returned as a word in the generators of ``G_{x0}`` of length ``n \leq 6``. Each atom of the word ``g`` is encoded as defined in the header file ``mmgroup_generators.h``. The function stores ``g`` as a word of generators in the array ``pg_out`` and returns the length ``n`` of that word. It returns a negative number in case of failure, e.g. if ``v`` is not of type 2. """ vtype = gen_leech2_subtype(v) if (vtype >> 4) != 2: raise ValueError("Vector is not short") result = [] for _i in range(4): if verbose: coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff vt = gen_leech2_subtype(v) coc_anchor = 0 if vt in [0x22]: w = mat24.gcode_weight(v >> 12) vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12) coc_anchor = mat24.lsbit24(vect) coc_syn = Cocode(coc).syndrome_list(coc_anchor) gcode = mat24.gcode_to_vect(v >> 12) print("Round %d, v = %s, subtype %s, gcode %s, cocode %s" % (_i, hex(v & 0xffffff), hex(vt), hex(gcode), coc_syn)) assert vtype == gen_leech2_subtype(v) if vtype == 0x21: exp = xi_reduce_odd_type2(v) vtype = 0x22 elif vtype == 0x22: exp = xi_reduce_octad(v) if exp < 0: w = mat24.gcode_weight(v >> 12) vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12) src = mat24.vect_to_list(vect, 4) dest = [0, 1, 2, 3] v = apply_perm(v, src, dest, 4, result, verbose) exp = xi_reduce_octad(v) assert exp >= 0 vtype = 0x20 elif vtype == 0x20: exp = 0 # map v to stadard cocode word [2,3] if v & 0x7fffff != 0x200: syn = (mat24.cocode_syndrome(v, 0)) src = mat24.vect_to_list(syn, 2) v = apply_perm(v, src, [2, 3], 2, result, verbose) # correct v2 if v2 is the cocode word [2,3] + Omega if v & 0x800000: atom = 0xC0000200 # operation y_d such that d has odd scalar # product with cocode word [2,3] v = gen_leech2_op_atom(v, atom) result.append(atom) assert v & 0xffffff == 0x200 return np.array(result, dtype=np.uint32) else: raise ValueError("WTF") if exp: exp = 0xE0000003 - exp v = gen_leech2_op_atom(v, exp) result.append(exp) raise ValueError("WTF1")
def test_Parker_loop(): print("\nTesting operation on Parker loop") for i in range(200): # Test power map, inveriosn, sign, theta, and conversion to GCode n1 = randint(0, 0x1fff) p1 = PLoop(n1) assert p1.ord == n1 == p1.gcode + 0x1000 * (1 - p1.sign) / 2 if (i < 2): print("Testing Parker loop element", p1, ", GCode = ", GCode(p1)) assert len(p1) == mat24.gcode_weight(n1) << 2 assert p1.theta() == Cocode(mat24.ploop_theta(n1)) assert p1 / 4 == p1.theta(p1) == Parity(mat24.ploop_cocycle(n1, n1)) assert p1**2 == PLoopZ(p1 / 4) == (-PLoopZ())**(p1 / 4) assert p1**(-5) == PLoopZ(p1 / 4) * p1 == (-1)**(p1 / 4) * p1 == 1 / p1 assert (1 / p1).ord ^ n1 == (mat24.gcode_weight(n1) & 1) << 12 assert -1 / p1 == -p1**3 == -(1 / p1) assert p1 * (-1 / p1) == PLoopZ(1) == -PLoopZ() assert abs(p1).ord == GCode(p1).ord == p1.ord & 0xfff assert p1 != GCode(p1) assert +p1 == 1 * p1 == p1 * 1 == p1 assert p1 != -p1 and p1 != ~p1 assert (-p1).ord == p1.ord ^ 0x1000 assert (~p1).ord == p1.ord ^ 0x800 s, o, p1_pos = p1.split() assert s == (p1.ord >> 12) & 1 assert o == (p1.ord >> 11) & 1 assert p1.sign == (-1)**s assert p1_pos.ord == p1.ord & 0x7ff assert PLoopZ(s, o) * p1_pos == p1 assert PLoopZ(0, o) * p1_pos == abs(p1) assert PLoopZ(s + 1, o) * p1_pos == -p1 assert -p1 == -1 * p1 == p1 * -1 == p1 / -1 == -1 / p1**-5 assert PLoopZ(s, 1 + o) * p1_pos == ~p1 assert PLoopZ(1 + s, 1 + o) * p1_pos == ~-p1 == -~p1 == ~p1 / -1 assert 2 * p1 == GCode(0) == -2 * GCode(p1) assert -13 * p1 == GCode(p1) == 7 * GCode(p1) if len(p1) & 7 == 0: assert p1**Parity(1) == p1 assert p1**Parity(0) == PLoop(0) else: with pytest.raises(ValueError): p1**Parity(randint(0, 1)) assert p1.bit_list == mat24.gcode_to_bit_list(p1.value & 0xfff) assert p1.bit_list == GcVector(p1).bit_list assert p1.bit_list == GCode(p1).bit_list assert PLoop(GcVector(p1) + 0) == PLoop(GCode(p1) + 0) == abs(p1) assert p1 + 0 == 0 + p1 == GCode(p1) + 0 == 0 + GCode(p1) assert Cocode(GcVector(p1)) == Cocode(0) assert p1 / 2 == Parity(0) # Test Parker loop multiplication and commutator n2 = randint(0, 0x1fff) p2 = PLoop(n2) coc = Cocode(mat24.ploop_cap(n1, n2)) if (i < 1): print("Intersection with", p2, "is", coc) p2inv = p2**-1 assert p1 * p2 == PLoop(mat24.mul_ploop(p1.ord, p2.ord)) assert p1 / p2 == p1 * p2**(-1) assert p1 + p2 == p1 - p2 == GCode(p1 * p2) == GCode(n1 ^ n2) assert (p1 * p2) / (p2 * p1) == PLoopZ((p1 & p2) / 2) assert p1 & p2 == coc assert p1.theta() == Cocode(mat24.ploop_theta(p1.ord)) assert p1.theta(p2) == Parity(mat24.ploop_cocycle(p1.ord, p2.ord)) assert (p1 & p2) / 2 == p1.theta(p2) + p2.theta(p1) assert p1 & p2 == p1.theta() + p2.theta() + (p1 + p2).theta() assert int((p1 & p2) / 2) == mat24.ploop_comm(p1.ord, p2.ord) assert GcVector(p1 & p2) == GcVector(p1) & GcVector(p2) assert ~GcVector(p1 & p2) == ~GcVector(p1) | ~GcVector(p2) assert Cocode(GcVector(p1 & p2)) == p1 & p2 # Test associator n3 = randint(0, 0x1fff) p3 = PLoop(n3) assert p1 * p2 * p3 / (p1 * (p2 * p3)) == PLoopZ(p1 & p2 & p3) assert int(p1 & p2 & p3) == mat24.ploop_assoc(p1.ord, p2.ord, p3.ord) i = randint(-1000, 1000) par = Parity(i) s3 = ((p3 & p1) & p2) + par assert s3 == ((p3 & p1) & p2) + par assert s3 == i + (p1 & (p2 & p3)) assert s3 == par + (p1 & (p2 & p3)) # Test some operations leading to a TypeError with pytest.raises(TypeError): p1 & p2 & p3 & p1 with pytest.raises(TypeError): coc & coc with pytest.raises(TypeError): GCode(p1) * GCode(p2) with pytest.raises(TypeError): 1 / GCode(p2) with pytest.raises(ValueError): coc / 4 with pytest.raises(TypeError): p1 * coc with pytest.raises(TypeError): coc * p1 types = [GcVector, GCode, Cocode, PLoop] for type_ in types: with pytest.raises(TypeError): int(type_(0)) print("Parker Loop test passed")
def baby_value_A(self): r"""Yet to be documented!!!""" return self.v.eval_A(XLeech2(Cocode([2,3])))
######################################################################## # Obtaining samples of transformed axes ######################################################################## ######################################################################## ######################################################################## # Generate a random element of Co_2 ######################################################################## FIXED_PAIR = [3, 2] FIXED_TUPLE = ("I", 3, 2) PI22 = set([0, 1] + list(range(4, 24))) PI7 = [2, 3, 0, 1, 4, 5, 8] StdCocodeVector = Cocode(FIXED_PAIR) EvenGCodeMask = None for i in range(12): if (PLoop(1 << i) & StdCocodeVector).ord: assert EvenGCodeMask == None EvenGCodeMask = 0xfff ^ (1 << i) assert EvenGCodeMask is not None def rand_pi_m22(): r = randint(0, 1) img = [2 + r, 3 - r] + sample(PI22, 3) syn = GcVector(img).syndrome_list() compl = set(range(24)) - set(img + syn) img += sample(syn, 1) + sample(compl, 1) result = AutPL('r', zip(PI7, img))
######################################################################## ######################################################################## PROCESSES = 0 ######################################################################## ######################################################################## # The group elements and vectors and the vector space to be used ######################################################################## ######################################################################## # The central involution in the subgroup ``G_x0``- g_central = G("x", 0x1000) # The standard 2A element in the monste froup g_axis = G("d", Cocode([2, 3])) # Tuple describing the standard 2A axis vector v_start_tuple = ("I", 3, 2) # The standars 2A axis vector v_axis = V15(*v_start_tuple) ######################################################################## ######################################################################## # Class for storing a pair (g, v), g in MM, v an axis ######################################################################## ######################################################################## TYPE_SCORES = { '2A': 11,