def test_xsp2co1_elem_involution_class(verbose=0): global INVOLUTION_MAP minus = Xsp2_Co1('x', 0x1000) length, classes = 0, set() for data, s in INVOLUTION_SAMPLES: g = Xsp2_Co1(s) cl = xsp2co1_elem_involution_class(g._data) if verbose: print("%04x" % cl, data) classes.add(cl) length += 1 for j in range(100): h = g**Xsp2_Co1('r', 'G_x0') #print(" ", h) assert cl == xsp2co1_elem_involution_class(h._data) chi = get_monster_character(cl) assert chi == data[1][0], (chi, data[1][0]) Co1_cls = Co1_class(g) assert (cl >> 8) & 0xf == Co1_cls, ((cl >> 8) & 0xf, Co1_cls) cl_neg = xsp2co1_elem_involution_class((g * minus)._data) fused = cl == cl_neg assert (cl >> 12) & 1 == (not fused), (hex(cl), hex(cl_neg)) o = g.order() assert o == (cl >> 4) & 0xf sqrt_minus1 = bool(cl >> 13) if sqrt_minus1: assert o & 1 == 0, o assert g**(o // 2) == minus elif o & 1 == 0: assert g**(o // 2) != minus INVOLUTION_MAP[cl] = data[1] assert len(classes) == length
def test_xsp2_conjugate(verbose=0): """Test the conjugation of Pauli matrix with unitary matrix""" l0, l1, l2 = Xsp2_Co1(), Xsp2_Co1('l', 1), Xsp2_Co1('l', 2) assert l1**2 == l2 assert l1**3 == l0 for ntest, (g_mm, xs) in enumerate(create_conjugate_data()): g = Xsp2_Co1(g_mm) xs_g_all = [Xsp2_Co1.group.from_xsp(x) for x in xs] xs_all = [x.as_xsp() for x in xs_g_all] ok = xs == xs_all o = g.order() assert o in Gx0_ORDERS if verbose or not ok: print("\nTest %d:\ng = %s" % (ntest, g)) print("g has order %d" % o) print("v =", [hex(x) for x in xs]) if not ok: print("Input and recomputed xsp2 vectors v:") print("v =", [hex(x) for x in xs_all]) err = "Error in recomputation of extraspecial vector" raise ValueError(err) conj = g.xsp_conjugate(xs) ref_conj = [(g**-1 * x * g).as_xsp() for x in xs_g_all] ref_conj1 = [conj_x_by_word(x, g_mm) for x in xs] ref_ok = ref_conj == ref_conj1 if not ref_ok: print("Conjugation of v with g =\n", g) print("v =", [hex(x) for x in xs]) print("Reference for v * g via direct calculation") print([hex(x) for x in ref_conj]) print("Reference using C function gen_leech2_op_word") print([hex(x) for x in ref_conj1]) err = "Error in reference for conjugation in group G_{x1}" raise ValueError(err) ok = ref_ok and conj == ref_conj1 if verbose or not ok: if not verbose: print("Conjugation of v with g =\n", g) print("v =", [hex(x) for x in xs]) print("Conjugated expected:\n", [hex(x) for x in ref_conj]) if not ok: print("Conjugated obtained:\n", [hex(x) for x in conj]) err = "Error in conjugation in group G_{x1}" raise ValueError(err) conj_nosign = g.xsp_conjugate(xs, sign=False) mask = (1 << 24) - 1 assert conj_nosign == [x & mask for x in conj]
def characters(g): a = np.zeros(4, dtype=np.int32) assert xsp2co1_traces_all(Xsp2_Co1(g)._data, a) == 0 chi24, chisq24, chi4096, chi98280 = map(int, a[:4]) chi299 = (chi24**2 + chisq24) // 2 - 1 chi_M = chi299 + chi98280 + chi24 * chi4096 return chi_M, chi299, chi24, chi4096, chi98280
def invariant_type(g): iv, _1, ortho = Xsp2_Co1(g)._involution_invariants() iv_len = 12 while iv_len and iv[iv_len - 1] == 0: iv_len = iv_len - 1 v0, v1 = (int(iv[0]) >> 24) & 7, (int(iv[1]) >> 24) & 7 ct2 = invariant_count_type2(iv) return iv_len, v0, v1, gen_leech2_type(ortho), ct2
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 rand_n_elem(): """Return random element of the group ``N_x0`` The group ``N_x0`` has structure ``2^{1+24}.2^{11}.M_24``. Multiplying a vector in the Leech lattice mod 2 with an element of ``N_x0`` does not change its subtype. """ return Xsp2_Co1([(x, 'r') for x in "dxpy"])
def character_testcases(): data = [ [], [("x", 0x1f4c), ("d", 0x375)], ] for d in data: yield Xsp2_Co1(d) for i in range(200): yield rand_xsp2co1_elem()
def display_involution_invariants(g): iv, v1, v0 = Xsp2_Co1(g)._involution_invariants() print("Involution invariants of", MM(g), ":") for i in range(12): v = int(iv[i]) if i and v == 0: break print("0x%06x 0x%01x 0x%06x" % ((v >> 32) & 0xffffff, (v >> 24) & 0xf, v & 0xffffff)) print("Orthogonal: 0x%06x, 0x%06x\n" % (v1, v0))
def test_involution_samples(verbose=0): if verbose: print("Test character calculation on involutions in G_x0/Q_x0") for (_1, chi, _2), g_str in INVOLUTION_SAMPLES: chi_576 = 2 * (chi[1] + 1) - chi[2]**2 chi_ref = [chi[2], chi_576, chi[3], chi[4]] g = Xsp2_Co1(g_str) for j in range(4): w = rand_xsp2co1_elem() assert xsp2co1_traces(g**w) == chi_ref
def conj_G_x0_to_Q_x0(g): gg = Xsp2_Co1(g) a = np.zeros(7, dtype=np.uint32) lv = chk_qstate12(xsp2co1_elem_conj_G_x0_to_Q_x0(gg._data, a)) length, q = lv >> 25, lv & 0x1ffffff h = MM0('a', a[:length]) gh = MM0(g)**h assert gh.in_Q_x0() assert gh == MM0('q', q) return h
def transversal_basis(g): a = Xsp2_Co1(g)._involution_invariants()[0] while len(a) and int(a[-1]) == 0: a = a[:-1] while len(a) and int(a[0]) & 0x7000000: a = a[1:] a = [int(x) & 0xffffff for x in a] bl = set(range(1, 25)) - set([x.bit_length() for x in a]) assert len(bl) == 24 - len(a) return [1 << (x - 1) for x in bl]
def test_subtype(verbose=0): OMEGA = XLeech2(~PLoop()) if verbose: print("OMEGA = ", OMEGA) types = set() for v in subtype_testdata(): g = MM('c', v) v2 = Xsp2_Co1(g) v2_subtype = v2.subtype v2ref = (OMEGA * g) v2ref_subtype = v2ref.subtype if verbose: print("v = ", v) print("g = ", g) print("v2 = ", v2, ", subtype =", v2_subtype) print("v2ref = ", v2ref, ", subtype =", v2ref_subtype) assert v2_subtype == v2ref_subtype, (v2_subtype, v2ref_subtype) types.add(v2_subtype) assert len(types) == 6
def invariant_basis(g): a = Xsp2_Co1(g)._involution_invariants()[0] return [int(x) & 0xffffff for x in a]
def xsp2xco1_xsp2(v): pl = PLoop(v >> 12) coc = Cocode(v) return Xsp2_Co1([("x", v >> 12), pl.theta(), coc])
def rand_xsp2co1_elem(): return Xsp2_Co1('r', 'G_x0')
def do_test_involution_invariants(g, ref_invariants, verbose=0): errors = 0 error_text = None def check(condition, bit, text=None): nonlocal errors, error_text if not condition: errors |= 1 << bit if not error_text: error_text = text g.reduce() if verbose: print("g =", g) gg = Xsp2_Co1(g) ref_ord, ref_chi, ref_involution_invariants = ref_invariants ref_chi = ref_chi[:4] invar, v1, v0 = gg._involution_invariants() ## invar[0] = int(invar[0]) & 0x3ffffff # this produces an error errors = 0 check(ref_ord[0] == gg.order(), 0, "order of g") check(ref_ord[1] == XLeech2(gg**2).type, 1, "order of g**2") check(ref_chi == g.chi_G_x0(), 2, "characters of g") if int(invar[0]) & 0x8000000: check((gg**2).in_Q_x0(), 3, "Invariant in involution") check((int(invar[0]) >> 24) & 7 == ref_involution_invariants[1], 4, "invar[0]") check((int(invar[1]) >> 24) & 7 == ref_involution_invariants[2], 5, "invar[1]") check( gen_leech2_type(v0) == ref_involution_invariants[3], 6, "leech2_type") check( invariant_count_type2(invar) == ref_involution_invariants[4], 7, "type-2 vector count") invar = [int(x) for x in invar if int(x)] check( len(invar) == ref_involution_invariants[0], 8, "length of invariants") for i, x in enumerate(invar[2:]): check(x & 0xff000000ff000000 == 0, 9, "bits in invaraiant[%d]" % i) data = [x for x in invar if (x >> 26) & 1 == 0] pre_data = [x for x in invar if (x >> 26) & 1 == 1] preimages = [x >> 32 for x in data] images = [x & 0x1ffffff for x in data] g_images = [x for x in gg.xsp_conjugate(list(preimages))] g_images2 = [x for x in gg.xsp_conjugate(list(images))] zipp = zip(preimages, images, g_images, g_images2) if verbose: print("Involution invariants found (length = %d)" % len(invar)) if len(pre_data) == 1: pre_l = [int(pre_data[0]) >> 24, int(pre_data[0]) & 0xffffff] print("Prefix line", [hex(x) for x in pre_l]) print(", ".join(["preimage", "image", "g_image", "g_image2", "t"])) for i, (preim, im, g_im, g_im2) in enumerate(zipp): t = preim ^ im ^ g_im if verbose: print([hex(x) for x in (preim, im, g_im, g_im2, t)]) check((preim ^ im ^ g_im) & 0xffffff == 0, 10, "(preimage ^ image ^ g_image)[%d]" % i) check(g_im2 == im & 0xffffff, 11, " g_image[%d]" % i) # test conjugation istate = invariant_status(ref_invariants) v = xsp2co1_elem_find_type4(gg._data, 0) if not errors: if ref_chi[0] in (196883, 275, 4371): # The g is of type 1A, 2B or 2A in the monster check(istate >= 2, 12, "istate (= %s)" % istate) if not errors: if istate == 0: check(v <= 0, 13, "xsp2co1_elem_find_type4(), succeeded but should not") else: check(v > 0, 14, "xsp2co1_elem_find_type4() not successful") mv = MM0("c", v)**-1 h = g**mv if errors == 0 and istate > 1: check(h.in_N_x0(), 15, "conjugating element to N_x0, h=" + str(h)) if not errors: h1 = conj_G_x0_to_Q_x0(g) ok = (g**h1).in_Q_x0() check(ok, 16, "conjugating element to Q_x0") if not errors and istate == 3: _, a = gg.conjugate_involution(MM0) check(g**a == Z, 17, "conjugating element to centre of Q_x0") if errors: print("\nError in testing involution invariants") print("\nError status =", hex(errors)) if error_text: print("Error in " + error_text) print("g =", g) print("g as an instance of Xsp2_Co1:") for i in range(26): print(" 0x%016x" % gg.data[i]) print("istate =", istate) print("Expected Invariants:", ref_invariants) print("Conjugtion status expected:", istate) print("Conjugation vector:", hex(v)) print("Involution invariants obtained") for i, x in enumerate(invar): print("%2d: 0x%014x" % (i, x)) length = ref_invariants[2][0] if 8 <= length <= 9: coset = ref_invariants[2][4] > 0 _invar = np.array(invar + [0] * 12, dtype=np.uint64) v1 = xsp2co1_involution_find_type4(_invar, coset) print("Low level conjugation vector:", hex(v1)) try: from mmgroup.clifford12 import xsp2co1_involution_error_pool error_pool = np.zeros(64, dtype=np.uint64) length = xsp2co1_involution_error_pool(error_pool, len(error_pool)) if length: s = "Error pool from function xsp2co1_involution_invariants" print(s) for i, x in enumerate(error_pool[:length]): print("%2d: 0x%014x" % (i, x)) except: pass err = "Error in involution invariants" raise ValueError(err)
print(table) ##################################################################### # Test computation of characters in group G_{x0} ##################################################################### assert len(ClassOrders) == len(CharacterValues) CharacterDict = defaultdict(set) for order, char_value in zip(ClassOrders, CharacterValues): CharacterDict[order].add(char_value) #print(CharacterDict) Xsp2_Co1_Element = type(Xsp2_Co1()) def character(g, verbose=0): assert isinstance(g, Xsp2_Co1_Element) a = xsp2co1_traces(g) if verbose: print("Subcharacters", a) chi24, chisq24, chi4096, chi98260 = map(int, a[:4]) chi299 = (chi24**2 + chisq24) // 2 - 1 assert chi24 >= 0 if chi24 == 0: assert chi4096 >= 0 chi_M = chi299 + chi98260 + chi24 * chi4096 #print("MMMM", MM0(g)) chi_g = MM0(g).chi_G_x0() assert chi_g == (chi_M, chi299, chi24, chi4096) return chi_M