コード例 #1
0
ファイル: construct_mm.py プロジェクト: Martin-Seysen/mmgroup
def iter_rand_mm(quality):
    r"""Return a random element of the monster group

    The function returns a random element of the monster group.
    Here ``quality`` means a measure for the quality of the
    randimization process, where a higher value menas that
    the distribution of the elements is closer to uniform.

    If ``quality`` is an integer ``k`` then a product containing
    ``k`` powers of the triality element it generated. Here the
    default value creates an almost uniform distribution.

    In future versions the default value of parameter ``quality``
    may correspond to the generation of a truly uniform
    distribution.
    """
    a = np.zeros(10, dtype=np.uint32)
    seed = rand_get_seed()
    len_a = xsp2co1_rand_word_G_x0(a, seed)
    if not 0 <= len_a <= 10:
        raise ValueError(ERR_RAND_INTERN)
    yield from a[:len_a]
    for k in range(quality):
        yield 0x50000001 + gen_rng_modp(2, seed)
        c = 0
        while gen_leech2_type(c) != 4:
            c = gen_rng_modp(0x1000000, seed)
        len_a = gen_leech2_reduce_type4(c, a)
        mm_group_invert_word(a, len_a)
        if not 0 <= len_a <= 6:
            raise ValueError(ERR_RAND_INTERN)
        yield from a[:len_a]
コード例 #2
0
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
コード例 #3
0
ファイル: test_reduce.py プロジェクト: Martin-Seysen/mmgroup
def type2_ortho_testdata(ntests):
    """Yields special type-2 vectors in the Leech lattice mod 2

    These type-2 vectors are orthogonal to the vector BETA in the 
    real Leech lattice and given in **Leech lattice encoding**.
    """
    for v in type2_testdata(2 * ntests):
        if gen_leech2_type(v ^ BETA) == 4:
            yield v
コード例 #4
0
ファイル: xleech2.py プロジェクト: Martin-Seysen/mmgroup
    def type(self):
        r"""Return the type of the element of :math:`Q_{x0}`.

        This is equal to the type of the corresponding vector
        :math:`v` in the Leech lattice :math:`\Lambda` modulo 2. 
        The type of a vector :math:`v \in \Lambda / 2 \Lambda` 
        is the halved norm of the shortest  vector in the set 
        :math:`v + 2 \Lambda`. That type is equal to 0, 2, 3 or 4.
        """
        return gen_leech2_type(self.value)
コード例 #5
0
def xsp2xco1_v2type(vtype):
    global v2_types
    try:
        return xsp2xco1_xsp2(v2_types[vtype])
    except KeyError:
        assert vtype in [2, 3, 4]
        for i in range(10000):
            v = randint(0, 0xffffff)
            if gen_leech2_type(v) == vtype:
                v2_types[vtype] = xsp2xco1_xsp2(v)
                return v2_types[vtype]
        raise ValueError("No Leech lattice vector of type", vtype)
コード例 #6
0
    def type_Q_x0(self):
        r"""Return type of element if it is in the subgroup :math:`Q_{x0}`

        If the element is in the subgroup :math:`Q_{x0}` of the monster
        then the function returns the type of the vector in the Leech 
        lattice modulo 2 corresponding to this element. That type is
        0, 2, 3, or 4.

        The function raises ValueError if the element is not
        in the subgroup :math:`Q_{x0}`. 
        """
        v = self.as_Q_x0_atom()
        return gen_leech2_type(v)
コード例 #7
0
ファイル: xleech2.py プロジェクト: Martin-Seysen/mmgroup
def rand_xleech2_type(vtype):
    if vtype in [3, 4]:
        for i in range(1000):
            v = randint(0, 0x1ffffff)
            if gen_leech2_type(v) == vtype:
                return v
        raise ValueError(ERR_XL_RAND)
    if vtype == 0:
        return 0
    if vtype == 2:
        ve = randint(300, 98579)
        vs = mm_aux_index_extern_to_sparse(ve)
        sign = randint(0, 1)
        return mm_aux_index_sparse_to_leech2(vs) ^ (sign << 24)
    raise ValueError(ERR_XL_RAND)
コード例 #8
0
ファイル: test_reduce.py プロジェクト: Martin-Seysen/mmgroup
def test_reduce_type_4(ntests=500, verbose=0):
    """Test function ``reduce_type4`` """
    for n, v in enumerate(type4_testdata(ntests)):
        if verbose:
            print(" \nTest %d, v = %s, subtype  =%s" %
                  (n + 1, hex(v), hex(gen_leech2_subtype(v))))
        op = reduce_type4(v, verbose)
        w = gen_leech2_op_word(v, op, len(op))
        assert w & 0xffffff == 0x800000, hex(w)
        if gen_leech2_type(v ^ BETA) == 2:
            b = gen_leech2_op_word(BETA, op, len(op))
            assert b & 0xffffff == BETA, hex(b)
        a = np.zeros(6, dtype=np.uint32)
        l = gen_leech2_reduce_type4(v, a)
        if l < 0:
            err = "Error %s in function gen_leech2_reduce_type4"
            raise ValueError(err % hex(l & 0xffffffff))
        a = a[:l]
        assert list(a) == list(op), ((a), (op))
コード例 #9
0
def find_type4_testcases(ncases = 1):
    data = [
        ([0x800000, 0x800700, 0], 0,  0x800000), 
    ]
    for a, v2, v_best in data:
        yield np.array(a, dtype = np.uint32), v2, v_best
    for i in range(500):
        a = [rand_type_40_vector()] + [randint(0x1000, 0x7fffff) 
            for i in range(4)]
        best = a[0] if gen_leech2_type(a[0]) == 4 else None
        shuffle(a)
        yield np.array(a, dtype = np.uint32), 0, best
    lengths = list(range(20, 100, 3)) + list(range(2000, 2100,7))
    for i in lengths:
        a = np.random.randint(0, 0xffffff, i, dtype = np.uint32)
        yield a, 0, None
    for i in range(1000):
        v2, a = rand_type2_type4_list(3, 5)
        yield a, v2, None
コード例 #10
0
ファイル: construct_mm.py プロジェクト: Martin-Seysen/mmgroup
def iter_c(tag, r):
    if isinstance(r, str):
        if r == 'r':
            c = rand_type4_vector()
        else:
            raise ValueError(ERR_LEECH2)
    elif isinstance(r, Integral):
        c = r & 0xffffff
    else:
        try:
            c = r.as_Q_x0_atom()
            assert isinstance(c, Integral)
        except:
            raise TypeError(ERR_LEECH2)
    if gen_leech2_type(c) != 4:
        raise ValueError(ERR_LEECH2)
    a = np.zeros(6, dtype=np.uint32)
    len_a = gen_leech2_reduce_type4(c, a)
    mm_group_invert_word(a, len_a)
    yield from a[:len_a]
コード例 #11
0
def check_leech2_subtype(x, t_expected):
    """Test computation of subtype of vector in Leech lattice mod 2

    Given a vector ``x`` in the Leech lattice mod 2 in **Leech 
    lattice encoding**, the function checkse if the subtype of ``x``
    is correctly computed as the value ``t_expected``.

    Therefore it computes the subtype with function ``gen_leech2_subtype``
    in file ``gen_leech.c`` and checks it against ``subtype``. This 
    function also checks function ``gen_leech2_type2``.   
    """
    t = gen_leech2_subtype(x)
    ok = t == t_expected
    if not ok:
        print("Error: expected Leech type: %s, obtained: %s" %
              (hex(t_expected), hex(t)))
        display_leech_vector(x)
        err = "Error in computing Leech type"
        raise ValueError(err)
    expected_type2 = t_expected if (t_expected >> 4) == 2 else 0
    found_type2 = gen_leech2_type2(x)
    ok = expected_type2 == found_type2
    if not ok:
        print("Error:  x = %s, Leech type: %s" % (hex(x), hex(t_expected)),
              expected_type2, hex(found_type2))
        err = "Function gen_leech2_subtype2 failed"
        raise ValueError(err)
    alt_found_type2 = alternative_type2(x)
    is_type2 = (t_expected >> 4) == 2
    ok = is_type2 == alt_found_type2
    if not ok:
        print("Error:  x = %s, Leech type: %s" % (hex(x), hex(t_expected)),
              is_type2, alt_found_type2)
        err = "Function xsp2co1_leech2_count_type2 failed"
        #raise ValueError(err)
    if not is_type2:
        assert not found_type2
    assert gen_leech2_type(x) == t >> 4
コード例 #12
0
ファイル: test_reduce.py プロジェクト: Martin-Seysen/mmgroup
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")
コード例 #13
0
def eval_type4(v, v2 = 0):
    value = VALUE_T4[gen_leech2_subtype(v)]
    if v2 & 0xffffff and gen_leech2_type(v ^ v2) != 2:
        value = 5
    return min(0x5000000, (v & 0xffffff) + (value << 24))
コード例 #14
0
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)
コード例 #15
0
ファイル: construct_mm.py プロジェクト: Martin-Seysen/mmgroup
def rand_type4_vector():
    c = 0
    while gen_leech2_type(c) != 4:
        c = randint(0, 0xffffff)
    return c
コード例 #16
0
def leech_type(v2):
    """Return type of vector ``v2`` in the Leech lattice mod 2"""
    return gen_leech2_type(v2)