def test_bitmatrix_echelon(verbose = 0):
    for ntest, (m, imin, imax) in enumerate(create_echelon_matrices()):
         m1h = np.array(m, dtype = np.uint64, copy = True)
         j0h, nh = imax + 1, imax - imin
         lenh = bitmatrix64_echelon_h(m1h, len(m1h), j0h, nh)
         m1h = list(m1h)
         lenh_ref, m1h_ref =  ref_echelon(m, j0h, nh)
         ok_h = m1h == m1h_ref and lenh == lenh_ref

         m1l = np.array(m, dtype = np.uint64, copy = True)
         j0l, nl = imin, imax - imin
         lenl = bitmatrix64_echelon_l(m1l, len(m1l), j0l, nl)
         m1l = list(m1l)
         lenl_ref, m1l_ref =  ref_echelon(m, j0l, nl, False)
         ok_l = m1l == m1l_ref and lenl == lenl_ref

         ok = ok_h and ok_l
         if verbose or not ok:
              print("Test ", ntest)
              print("m =", [hex(x) for x in m], j0h, nh)
              print("echelon h", [hex(x) for x in m1h], lenh)
              print("expected", [hex(x) for x in m1h_ref], lenh_ref)
              if not ok_h:
                  err = "Error in function bitmatrix64_echelon_h"
                  raise ValueError(err)
              print("m =", [hex(x) for x in m], j0l, nl)
              print("echelon l", [hex(x) for x in m1l], lenl)
              print("expected", [hex(x) for x in m1l_ref], lenl_ref)
              if not ok_l:
                  err = "Error in function bitmatrix64_echelon_l"
                  raise ValueError(err)
def leech_echelon(a):
    a = np.copy(a)
    bitmatrix64_xch_bits(a, 12, 0x800)
    bitmatrix64_rot_bits(a, 1, 12, 0)
    k = bitmatrix64_echelon_h(a, len(a), 24, 24)
    bitmatrix64_rot_bits(a, 11, 12, 0)
    bitmatrix64_xch_bits(a, 12, 0x800)
    return a[:k]
def test_leech2_matrix_basis():
    for a in leech2_matrix_basis_testcases():
        a1 = np.array(a, dtype=np.uint64)
        k1 = bitmatrix64_echelon_h(a1, len(a1), 24, 24)
        a1 = leech_echelon(a1)
        a2 = np.zeros(24, dtype=np.uint64)
        k2 = leech2_matrix_basis(a, len(a), a2, 24)
        assert k1 == k2  # == k2a
        assert (a1[:k1] == a2[:k1]).all()
def test_leech2_matrix_orthogonal():
    for a in leech2_matrix_orthogonal_testcases():
        a1 = np.copy(a)
        o1 = np.zeros(24, dtype=np.uint64)
        ko1 = leech2_matrix_orthogonal(a, o1, len(a))
        o1 = o1[ko1:]
        ka1 = bitmatrix64_echelon_h(a1, len(a1), 24, 24)
        assert ka1 == ko1
        for v in a1:
            for w in o1:
                assert gen_leech2_scalprod(v, w) == 0
def test_leech2_matrix_radical():
    for a in leech2_matrix_orthogonal_testcases():
        a1 = np.copy(a)
        k1 = bitmatrix64_echelon_h(a1, len(a1), 24, 24)
        a1 = a1[:k1]
        o1 = np.zeros(24, dtype=np.uint64)
        ko1 = leech2_matrix_orthogonal(a1, o1, len(a))
        o1 = o1[ko1:]
        ko1 = 24 - ko1
        ko1 = bitmatrix64_echelon_h(o1, len(o1), 24, 24)
        kcap = bitmatrix64_cap_h(a1, o1, 24, 24)
        #print(k1, ko1, kcap)
        kcap1 = kcap[0]
        radical = a1[kcap1:k1]
        radical = leech_echelon(radical)

        a_copy = np.array(a, dtype=np.uint32)
        a2 = np.zeros(24, dtype=np.uint64)
        k2 = leech2_matrix_radical(a_copy, len(a_copy), a2, 24)
        a2 = a2[:k2]

        assert len(radical) == k2
        assert (a2 == radical).all()