def index_to_sparse(tag, i0=-1, i1=-1): r"""Auxiliary method for index_to_short Convert a tagged tuple ``(tag, i0, i1)`` to a sparse index. That tuple must refer to an index describing a short Leech lattice vector. See method ``index_to_short`` for details. """ i = 0x0 if isinstance(tag, Integral) and 300 <= tag < 98580: i = mm_aux_index_extern_to_sparse(tag) elif isinstance(tag, str) and len(tag) == 1: t = TAGS.find(tag) if t >= 1 and 0 <= i0 < 2048 and 0 <= i1 < 64: i = (t << 25) + (i0 << 14) + (i1 << 8) elif tag == "E" and 300 <= i0 < 98580: i = mm_aux_index_extern_to_sparse(i0) elif tag == "D" and 0 <= i0 < 24: i = (1 << 25) + (i0 << 14) + (i0 << 8) elif isinstance(tag, MMVector): sp = tag.as_sparse() if len(sp) == 1: i = sp[0] else: err = "Cannot convert object to short Leech lattice vector" raise TypeError(err) return i
def index_to_tuple(cls, index): """Convert linear index to tuple ``(tag, i0, i1)`` This method reverses the effect of method ``tuple_to_index``. Given a linear index ``0 <= i < 196884`` for a basis vector, the function returns that index as a tuple ``(tag, i0, i1)`` with ``tags`` one letter of the string ``"ABCTXYZ"`` and integers ``i0``, ``i1``. See method ``tuple_to_index`` for details. If ``index`` is an instance of class |MMVector|, which is a nonzero multiple of a basis vector, then the index of that basis vector is taken. """ if isinstance(index, Integral): if 0 <= i < 196884: i = mm_aux_index_extern_to_sparse(index) return TAGS[i >> 25], (i >> 14) & 0x7ff, (i >> 8) & 0x3f else: raise ValueError("MM vector index out of range") elif isinstance(index, MMVector): sp = index.as_sparse() if len(sp) == 1: i = sp[0] return TAGS[i >> 25], (i >> 14) & 0x7ff, (i >> 8) & 0x3f else: raise ValueError("MM vector is not multiple of basis vector") else: raise TypeError("Cannot convert object to MM index tuple")
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)
def do_test_rep_conversion(v): p = v.p space = MMVector sparse_space = SparseMmVector ranges = [ (0, 5, 1), (0, 50, 10), (randint(0, 23), 852, randint(13, 17)), (randint(852, 852 + 200), 196884, randint(390, 409)), ] for start, stop, step in ranges: data_sparse = v.as_bytes()[start:stop:step] data = v[start:stop:step] assert len(data_sparse) == len(data), (len(data_sparse), len(data)) assert (data_sparse == data).all(), (data_sparse, data) a = np.zeros(len(data), dtype=np.uint32) for i, index in enumerate(range(start, stop, step)): a[i] = mm_aux_index_extern_to_sparse(index) i_ext = mm_aux_index_sparse_to_extern(a[i]) assert i_ext == index, (hex(index), hex(a[i]), hex(i_ext)) mm_aux_mmv_extract_sparse(p, v.data, a, len(a)) assert (a & 0xff == data).all(), (a & 0xff, data)
def type2_testvectors(): """Yield short test vectors in the Leech lattice mod 2 The function yields pairs ``(v2, vtype)``, where ``v2 ``is a short vector (of type 2) in the Leech lattice mod 2 in **Leech lattice encoding**, and ``vtype`` is the subtype of ``v``. This function uses function from file mm_aux.c for converting random indices of the rep 196884x to short vectors. """ TEST_PARS = [ (300, 2 * 276, 50, 0x20), (852, 759 * 64, 500, 0x22), (49428, 2048 * 24, 500, 0x21), ] for (start, nvectors, ntests, vtype) in TEST_PARS: for i in range(ntests): v_extern = randint(start, start + nvectors - 1) v_sparse = mm_aux_index_extern_to_sparse(v_extern) v2 = mm_aux_index_sparse_to_leech2(v_sparse) assert v2 != 0, (v_extern, hex(v_sparse), hex(v2)) #print(v_extern, hex(v_sparse), hex(v2), hex(vtype)) yield v2, vtype
def rand_leech2(): ext = 300 + randint(0, 98279) sp = mm_aux_index_extern_to_sparse(ext) return mm_aux_index_sparse_to_leech2(sp)
from random import randint #, shuffle, sample import numpy as np import pytest from mmgroup import MM0, MMSpace, MMV from mmgroup.mm import mm_aux_index_extern_to_sparse from mmgroup.mm import mm_aux_index_sparse_to_leech2 from mmgroup.mm import mm_aux_index_leech2_to_sparse from mmgroup.mm15 import op_eval_X_find_abs as mm_op15_eval_X_find_abs LEECH_SHORT = np.zeros(98280, dtype = np.int32) for i in range(98280): sparse = mm_aux_index_extern_to_sparse(300 + i) l1 = LEECH_SHORT[i] = mm_aux_index_sparse_to_leech2(sparse) sparse1 = mm_aux_index_leech2_to_sparse(l1) assert sparse == sparse1, [hex(x) for x in (i, sparse, l1, sparse1)] V = MMV(15) v = V('R') def from_v(v_abs, value, value1 = 0): if not value1: a = [LEECH_SHORT[i] for i in range(98280) if v_abs[i] == value] return np.array(a, dtype = np.uint32)