def one_test_perm_from_map(h1, h2, ref_res, ref_p, verbose=0): if verbose: print("h1 =", h1) print("h2 =", h2) print("Expected return value:", ref_res) res, perm = mat24.perm_from_map(h1, h2) ok, ok_perm = res == ref_res, True if ref_p: ok_perm = perm == ref_p elif ref_res > 0: for i, x in enumerate(h1): ok_perm = ok_perm and perm[x] == h2[i] ok = ok and ok_perm if not verbose and not ok: print("h1 =", h1) print("h2 =", h2) print("Expected return value:", ref_res) if verbose or not ok: print("Obtained return value:", res) print("p =", perm) if res <= 0: if ref_p and ref_p != perm: print("Expected:\n ", ref_p) if not ok_perm: print("Permutation p is bad") if res != ref_res: print("Return value is bad") if not ok: err = "Test of function mat24.perm_from_map failed" raise ValueError(err) if ref_p or len(h1) <= 1: return # If no expected permutation is given, shuffle h1 and h2 # in the same way and test once more with shuffled h1, h2. lh = len(h1) ind = list(range(lh)) if lh > 2 else [1, 0] if (lh > 2): random.shuffle(ind) h1a = [h1[i] for i in ind] h2a = [h2[i] for i in ind] res1, perm1 = mat24.perm_from_map(h1a, h2a) assert res1 == res, (res1, res) assert perm1 == perm, (perm1, perm)
def rand_pi_mat22(): r"""Generate certain 'random' element of AutPL The function generates a random element ``e`` of the automorphism group ``AutPL`` of the Parker loop, such that the permutation in the Mathieu ``M24`` group corresponding to ``e`` preserves the set ``\{2, 3\}``. """ pi = AutPL('r', 'r') perm = pi.perm l_src = perm[2:4] shuffle(l_src) _, a = mat24.perm_from_map(l_src, [2, 3]) return pi * AutPL('r', a)
def rand_perm_vect(v, v_more): """ Let ``v`` be a list representing a vector in ``GF(2)^24`` and ``v_more`` be a list such that ``v + v_more`` is or contains an umbral heptad. The function returns to random images ``h1, h2`` of ``v`` under ``Mat24``, and also a (somehow) random permutation ``pi_ref`` that maps ``h1`` to ``h2``. """ pi1 = rand_perm() pi2 = rand_perm() h1 = [pi1[x] for x in v] h2 = [pi2[x] for x in v] vm = v + v_more h1m = [pi1[x] for x in vm] h2m = [pi2[x] for x in vm] return h1, h2, mat24.perm_from_map(h1m, h2m)[1]
def one_test_perm_map_lex(h1, h2, pi_ref, ref_res=None, verbose=1): errors = 0 if verbose: print("h1 =", h1) print("h2 =", h2) print("pi_ref:", pi_ref) print("Expected return value:", ref_res) assert [pi_ref[x] for x in h1] == h2 res, pi = mat24.perm_from_map(h1, h2) if verbose: print("pi:", pi) if pi > pi_ref: print("pi is greater than pi_ref") errors += 1 if res != ref_res: print("Obtained return value:", res) #assert pi <= pi_ref assert [pi[x] for x in h1] == h2 if errors > 0: print(errors, "lexical errors") assert res == ref_res assert errors == 0
def apply_perm(v, src, dest, n, log_list, verbose=0): r"""Apply permutation to vector in Leech lattice mod 2. The function computes a permutation :math:`\pi` that maps the entries of the array ``src`` of length ``n`` to the entries of the array ``dest`` (of the same length) in the given order. Let :math:`v_2` be the vector in the Leech lattice mod 2 given by parameter ``v2``. The function returns :math:`v_2 x_\pi`. Parameter ``v2`` and the return value are given in Leech lattice encoding. Parameter ``p_res`` points to an integer where the function stores the element :math:`x_\pi` as a generator of the monster group as as described in file ``mmgroup_generators.h``. That generator is stored with tag ``MMGROUP_ATOM_TAG_IP`` so that we can compute the inverse of :math:`\pi` very efficiently. We compute the inverse of the lowest permutation (in lexical order) that maps ``dest[:n]`` to ``src[:n]``. """ res, p = mat24.perm_from_map(dest[:n], src[:n]) assert res > 0, (res, dest[:n], src[:n]) p_inv = mat24.inv_perm(p) p_num = mat24.perm_to_m24num(p) log_list.append(0xA0000000 + p_num) xd = (v >> 12) & 0xfff xdelta = (v ^ mat24.ploop_theta(xd)) & 0xfff m = mat24.perm_to_matrix(p_inv) xd = mat24.op_gcode_matrix(xd, m) xdelta = mat24.op_cocode_perm(xdelta, p_inv) v_out = (xd << 12) ^ xdelta ^ mat24.ploop_theta(xd) if verbose: print("Apply permutation (mapping v to gcode %s):\n%s" % (hex(mat24.gcode_to_vect(v_out >> 12)), p_inv)) return v_out
def autpl_from_obj(d = 0, p = 0, unique = 1): """Try to convert tuple (d, p) to a Parker loop automorphism. Parameter ``d`` decribes a element of the Golay cocode as in the constructor of class ``Cocode``. It may be of type ``int``, ``str`` or an instance of class ``Cocode``. Pt defaults to ``0``. Alternatively, ``d`` may be an instance of class ``AutPL``. In this case, ``p`` must be set to its default value. Parameter ``p`` describes a element of the Mathieu group ``Mat24``. It defaults to the neutral element of ``Mat24``. It may be * An integer encoding the number of a permutation in ``Mat24``. * A list encoding a permutation in the Mathieu group ``Mat24``. * A zip object or a dictionary encodes such a permutation as a mapping. That mapping must contain sufficiently many entries to be unique. * The string 'r' encodes a random permutation in ``Mat24``. If parameter ``unique`` is ``True`` (default), then the parameter ``p`` must either be ``r`` or describe a unique permutation in ``Mat24``. Otherwise lowest possible permutation (in lexicographic order) is taken. The function returns a pair ``(cocode, permutation_number)``. """ if import_pending: complete_import() if isinstance(d, Integral): d_out = int(d) elif isinstance(d, Cocode): d_out = d.value elif isinstance(d, AutPL): d_out, p_out = d._cocode, d._perm_num if p: raise TypeError(ERR_AUTPL_P1 % type(d)) return d_out, p_out elif isinstance(d, str): d_out = Cocode(d).value else: try: f = autpl_conversions[type(d)] except KeyError: raise TypeError(ERR_AUTPL_TYPE % type(d)) if p: raise TypeError(ERR_AUTPL_P1 % type(d)) d_out, p_out = f(d) return d_out, p_out if p == 'r': return d_out, randint(0, MAT24_ORDER - 1) if isinstance(p, Integral): if 0 <= p < MAT24_ORDER: return d_out, int(p) err = "Bad number for permutation in Mathieu group Mat24" raise ValueError(err) if isinstance(p, (list, range)): if mat24.perm_check(p): err = "Permutation is not in Mathieu group M_24" raise ValueError(err) return d_out, mat24.perm_to_m24num(p) if isinstance(p, zip): p = dict(p) if isinstance(p, dict): h1, h2 = [list(t) for t in zip(*p.items())] res, perm = mat24.perm_from_map(h1, h2) if res == 1 or (res > 1 and not unique): return d_out, mat24.perm_to_m24num(perm) if res < 1: err = "Permutation is not in Mathieu group M_24" else: err = "Permutation in Mathieu group M_24 is not unique" raise ValueError(err)