Пример #1
0
 def randomize(self, prime):
     assert not self.randomized
     prev = None
     for i in xrange(0, len(self.bp)):
         d_i_minus_one = self.bp[i].zero.nrows()
         d_i = self.bp[i].zero.ncols()
         MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i_minus_one, d_i)
         MSZp_square = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i, d_i)
         if i != 0:
             MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i_minus_one, d_i)
             self.bp[i] = self.bp[i].group(MSZp, prime).mult_left(prev.adjoint())
         if i != len(self.bp) - 1:
             cur = MSZp_square.random_element()
             self.bp[i] = self.bp[i].group(MSZp, prime).mult_right(cur)
             prev = cur
     # compute S * B_0
     d_0 = self.bp[0].zero.nrows()
     d_1 = self.bp[0].zero.ncols()
     S = matrix.identity(d_0)
     for i in xrange(d_0):
         S[i, i] = random.randint(0, prime - 1)
     MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_0, d_1)
     self.bp[0] = self.bp[0].group(MSZp, prime).mult_left(S)
     # compute B_ell * T
     r = self.bp[-1].zero.nrows()
     c = self.bp[-1].zero.ncols()
     T = matrix.identity(c)
     for i in xrange(c):
         T[i, i] = random.randint(0, prime - 1)
     MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), r, c)
     self.bp[-1] = self.bp[-1].group(MSZp, prime).mult_right(T)
     self.randomized = True
Пример #2
0
 def pgl2_matrix_for_path(self, p):
     if p:
         return prod([self.pgl2_matrix_for_edge(e) for e in p[::-1]])
     else:
         RF = self.vertex_gram_matrices[0].base_ring()
         CF = RF.complex_field()
         return matrix.identity(CF, 2)
Пример #3
0
 def get_matrix_for_tet_and_face(self, tet, F):
     g = tet.GeneratorsInfo[F]
     if g == 0:
         tet = self.mcomplex.Tetrahedra[0]
         CIF = tet.ShapeParameters[simplex.E01].parent()
         return matrix.identity(CIF, 2)
     return self.mcomplex.GeneratorMatrices[g]
Пример #4
0
    def __init__(self, approx_hyperbolic_structure, bits_prec=53):

        if not (approx_hyperbolic_structure.exact_edges
                and approx_hyperbolic_structure.var_edges):
            raise Exception(
                "Did not pick exact/var edges: "
                "call HyperbolicStructure.pick_exact_and_var_edges.")

        self.mcomplex = approx_hyperbolic_structure.mcomplex
        self.exact_edges = approx_hyperbolic_structure.exact_edges
        self.var_edges = approx_hyperbolic_structure.var_edges
        self.bits_prec = bits_prec
        self.RIF = RealIntervalField(bits_prec)
        self.twoPi = self.RIF(2 * pi)

        self.initial_edge_lengths = vector(
            [self.RIF(e) for e in approx_hyperbolic_structure.edge_lengths])

        self.approx_inverse = (approx_hyperbolic_structure.
                               full_rank_jacobian_submatrix().change_ring(
                                   RealDoubleField()).inverse().change_ring(
                                       self.RIF))

        self.identity = matrix.identity(self.RIF, len(self.var_edges))

        self.certified_edge_lengths = None
Пример #5
0
 def _augment(M, r):
     nrows, ncols = M.dimensions()
     Z_1 = matrix.zero(nrows, r)
     Z_2 = matrix.zero(r, ncols)
     I_r = matrix.identity(r)
     tmp1 = M.augment(Z_1).transpose()
     tmp2 = Z_2.augment(I_r).transpose()
     return tmp1.augment(tmp2).transpose()
Пример #6
0
    def get_initial_cusp_triangle(self):
        tet = self.mcomplex.Tetrahedra[0]
        CIF = tet.ShapeParameters[simplex.E01].parent()
        m = matrix.identity(CIF, 2)

        corner = self.vertex_at_infinity.Corners[0]

        return (corner.Tetrahedron.Index, corner.Subsimplex, m)
Пример #7
0
 def _augment(M, r):
     nrows, ncols = M.dimensions()
     Z_1 = matrix.zero(nrows, r)
     Z_2 = matrix.zero(r, ncols)
     I_r = matrix.identity(r)
     tmp1 = M.augment(Z_1).transpose()
     tmp2 = Z_2.augment(I_r).transpose()
     return tmp1.augment(tmp2).transpose()
Пример #8
0
        def check_guptri_properties(self, A, B):
            S, T, P, Q, kstr = guptri(A, B)
            tol = 1e-12
            assert (P.H * A * Q - S).norm() < tol
            assert (P.H * B * Q - T).norm() < tol
            assert (P.H * P - matrix.identity(RDF, P.ncols())).norm() < tol
            assert (Q.H * Q - matrix.identity(RDF, Q.ncols())).norm() < tol
            kb = kcf_blocks(kstr)
            assert np.all(kb[:, 0] == 0) or kb[0, 0] < kb[1, 0]
            assert np.all(kb[:, -1] == 0) or kb[0, -1] > kb[1, -1]
            assert np.all(kb[0, 1:4] == kb[1, 1:4])

            # test that Y = A X + B X for some of the reducing subspaces
            for k in range(1, 5):
                Y, X = guptri(A, B, part=range(k))[2:4]
                AXBX = (A * X).augment(B * X)
                assert Y.ncols() == matrix_rank(AXBX, tol=1e-12)
                assert Y.ncols() == matrix_rank(AXBX.augment(Y), tol=1e-12)
Пример #9
0
 def test_block_triangular_form_1(t):
     # Test with no transformation needed
     M = matrix([
       [1, 0, 0],
       [2, 3, 0],
       [4, 5, 6]
     ])
     MM, T, B = block_triangular_form(M)
     t.assertEqual(MM, M)
     t.assertEqual(T, matrix.identity(3))
     t.assertEqual(sorted(B), [(0, 1), (1, 1), (2, 1)])
Пример #10
0
 def test_block_triangular_form_2(t):
     # Test with no transformation possible
     M = matrix([
       [1, 2, 3, 4],
       [5, 6, 7, 8],
       [9, 1, 2, 3],
       [4, 5, 6, 7]
     ])
     MM, T, B = block_triangular_form(M)
     t.assertEqual(MM, M)
     t.assertEqual(T, matrix.identity(4))
     t.assertEqual(B, [(0, 4)])
Пример #11
0
 def randomize(self, prime):
     assert not self.randomized
     prev = None
     for i in xrange(0, len(self.bp)):
         d_i_minus_one = self.bp[i].zero.nrows()
         d_i = self.bp[i].zero.ncols()
         MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)),
                            d_i_minus_one, d_i)
         MSZp_square = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i,
                                   d_i)
         if i != 0:
             MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)),
                                d_i_minus_one, d_i)
             self.bp[i] = self.bp[i].group(MSZp,
                                           prime).mult_left(prev.adjoint())
         if i != len(self.bp) - 1:
             cur = MSZp_square.random_element()
             self.bp[i] = self.bp[i].group(MSZp, prime).mult_right(cur)
             prev = cur
     # compute S * B_0
     d_0 = self.bp[0].zero.nrows()
     d_1 = self.bp[0].zero.ncols()
     S = matrix.identity(d_0)
     for i in xrange(d_0):
         S[i, i] = random.randint(0, prime - 1)
     MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_0, d_1)
     self.bp[0] = self.bp[0].group(MSZp, prime).mult_left(S)
     # compute B_ell * T
     r = self.bp[-1].zero.nrows()
     c = self.bp[-1].zero.ncols()
     T = matrix.identity(c)
     for i in xrange(c):
         T[i, i] = random.randint(0, prime - 1)
     MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), r, c)
     self.bp[-1] = self.bp[-1].group(MSZp, prime).mult_right(T)
     self.randomized = True
Пример #12
0
 def test_block_triangular_form_4(t):
     M = matrix([
       [1, 2, 3, 0, 0, 0],
       [4, 5, 6, 0, 0, 0],
       [7, 8, 9, 0, 0, 0],
       [2, 0, 0, 1, 2, 0],
       [0, 2, 0, 3, 4, 0],
       [0, 0, 2, 0, 0, 1]
     ])
     x = SR.var("dummy")
     T = matrix.identity(6)[random.sample(xrange(6), 6),:]
     M = transform(M, x, T)
     MM, T, B = block_triangular_form(M)
     t.assertEqual(MM, transform(M, x, T))
     t.assertEqual(sorted(s for o, s in B), [1, 2, 3])
     for o, s in B:
         for i in xrange(s):
             for j in xrange(s):
                 MM[o + i, o + j] = 0
     for i in xrange(6):
         for j in xrange(i):
             MM[i, j] = 0
     t.assertEqual(MM, matrix(6))
Пример #13
0
    def is_invertible(m):
        r, c = m.dimensions()
        if r != c:
            raise AssertionError("Not a square matrix in invertible check "
                                 "of VerifyHyperbolicStructureEngine.")

        RIF = m.base_ring()
        max_entry = RIF(1) / (r * c)

        real_m = matrix(RealDoubleField(), m)
        try:
            real_approx_inv = real_m.inverse()
        except ZeroDivisionError:
            return False

        approx_inv = real_approx_inv.change_ring(RIF)
        idMatrix = matrix.identity(RIF, r)
        t = approx_inv * m - idMatrix

        for row in t:
            for entry in row:
                if not (entry < max_entry):
                    return False
        return True
Пример #14
0
    def __init__(self, M, initial_shapes, bits_prec=None, dec_prec=None):
        """
        Initializes the KrawczykShapesEngine given an orientable SnapPy
        Manifold M, approximated solutions initial_shapes to the
        gluing equations (e.g., as returned by M.tetrahedra_shapes('rect'))
        and the precision to be used for the desired computations in either
        bits bits_prec or decimal digits dec_prec.

        This requires Sage since it uses Sage's ComplexIntervalField for its
        computations.

        Note that this will choose an independent set of edge equations and
        one equation per cusp. It is known that a solution to such a subset of
        rectangular gluing equations is also a solution to the full set of
        rectangular gluing equations::

            sage: from snappy import Manifold
            sage: M = Manifold("m019")

            sage: C = KrawczykShapesEngine(M, M.tetrahedra_shapes('rect'), bits_prec = 53)
            sage: C.expand_until_certified()
            True
            sage: C.certified_shapes # doctest: +ELLIPSIS
            (0.780552527850...? + 0.914473662967...?*I, 0.780552527850...? + 0.91447366296773?*I, 0.4600211755737...? + 0.6326241936052...?*I)

        Does not work with non-orientable manifolds::

            sage: M = Manifold("m000")
            sage: KrawczykShapesEngine(M, M.tetrahedra_shapes('rect'), bits_prec = 53)
            Traceback (most recent call last):
            ...
            Exception: Manifold needs to be orientable


        Or some non-hyperbolic manifolds::
        
            sage: Manifold("t02333(1,0)").tetrahedra_shapes(intervals = True)
            Traceback (most recent call last):
            ...
            RuntimeError: Could not certify shape intervals, either there are degenerate shapes or the precision must be increased.

        """

        # Require sage
        if not _within_sage:
            raise SageNotAvailable(
                "Sorry, the verify module can only be used within Sage")

        # Convert to precision in bits if necessary
        if dec_prec:
            self.prec = prec_dec_to_bits(dec_prec)
        elif bits_prec:
            self.prec = bits_prec
        else:
            raise Exception("Need dec_prec or bits_prec")

        # Setup interval types of desired precision
        self.CIF = ComplexIntervalField(self.prec)
        self.RIF = RealIntervalField(self.prec)

        # Verify that manifold is orientable
        if not M.is_orientable():
            raise Exception("Manifold needs to be orientable")

        # Initialize the shape intervals, they have zero length
        self.initial_shapes = vector(
            [self.CIF(shape) for shape in initial_shapes])

        # Get an independent set of gluing equations from snap
        self.equations = snap.shapes.enough_gluing_equations(M)
        self._make_sparse_equations()

        self.identity = matrix.identity(self.CIF, len(self.initial_shapes))

        CDF = ComplexDoubleField()

        # Could be sparse
        approx_deriv = self.log_gluing_LHS_derivatives(
            [CDF(shape) for shape in initial_shapes])
        approx_inverse_double = approx_deriv.inverse()
        self.approx_inverse = approx_inverse_double.change_ring(self.CIF)

        # Compute the term z0 - c * f(z0) in the formula for
        # the Krawczyk interval K(z0, [z], f)

        value_at_initial_shapes = self.log_gluing_LHSs(self.initial_shapes)

        self.first_term = (self.initial_shapes -
                           self.approx_inverse * value_at_initial_shapes)

        # Shapes have not been certified yet
        self.certified_shapes = None
Пример #15
0
def smith_normal_form(A, v):
    r""" Return the Smith normal form of the matrix ``A``.

    INPUT:

    - ``A`` -- a matrix over a field `K`
    - ``v`` -- a discrete valuation on `K`

    OUTPUT:

    a tuple`(D, S, T, rank)` `D, S, T` matrices, such that

    .. MATH::

        S\cdot A\codt T = D,

    where `S` and `T` are square invertible matrices over the valuation ring `R`
    of `v`, `D` is the Smith normal form of `A` over `R`, and `rank` is the rank of `D`.

    """
    K = A.base_ring()
    m = A.nrows()
    n = A.ncols()
    # assert all([v(a) >= 0 for a in A.coefficients()]), "A must have integral coefficients"
    D = copy(A)
    S = matrix.identity(K, m)
    T = matrix.identity(K, n)
    k = -1
    while not D.submatrix(k + 1, k + 1).is_zero():
        # the parameter k indicates that the rows i=0,..,k and columns j=0,..,k
        # are already in the required form
        i, j, e = find_pivot(v, D, k)
        # the entry D[i, j] is the next entry with the smallest valuation e
        switch_rows(D, k + 1, i)
        switch_columns(S, k + 1, i)
        switch_columns(D, k + 1, j)
        switch_rows(T, k + 1, j)
        assert A == S * D * T, "something is wrong!"
        # now D[k + 1, k + 1] is a nonzero entry, with minimal valuation e
        a0 = v.element_with_valuation(e)
        a = a0 / D[k + 1, k + 1]
        D.rescale_col(k + 1, a)
        T.rescale_row(k + 1, 1 / a)
        assert A == S * D * T, "something is wrong!"
        for j in range(k + 2, n):
            if not D[k + 1, j].is_zero():
                x = -D[k + 1, j] / a0
                D.add_multiple_of_column(j, k + 1, x)
                T.add_multiple_of_row(k + 1, j, -x)
                assert A == S * D * T, "something is wrong!"
        # now we kill the rest of the (k+1)th column
        for i in range(k + 2, m):
            if not D[i, k + 1].is_zero():
                x = -D[i, k + 1] / a0
                D.add_multiple_of_row(i, k + 1, x)
                S.add_multiple_of_column(k + 1, i, -x)
                assert A == S * D * T, "something is wrong!"
        if k < n - 1 and k < m - 1:
            k += 1
    assert v(S.determinant()) == 0, "S is not invertible!"
    assert v(T.determinant()) == 0, "T is not invertible!"
    return D, S, T, k + 1
Пример #16
0
def make_luts(field, sub_folder, seed, sparse=False):
    global FIELD, RING
    print(f"Making LUTs for {field}")

    ###############################################################################
    # Finite field arithmetic
    ###############################################################################
    folder = os.path.join(PATH, "fields", "data", sub_folder)
    if os.path.exists(folder):
        shutil.rmtree(folder)
    os.mkdir(folder)

    FIELD = field
    RING = PolynomialRing(field, names="x")
    characteristic = int(field.characteristic())
    order = int(field.order())
    dtype = np.int64 if order <= np.iinfo(np.int64).max else object
    alpha = field.primitive_element()
    # assert field.gen() == field.multiplicative_generator()

    d = {
        "characteristic": int(field.characteristic()),
        "degree": int(field.degree()),
        "order": int(field.order()),
        "primitive_element": I(field.primitive_element()),
        "irreducible_poly": [int(c) for c in field.modulus().list()[::-1]]
    }
    save_json(d, folder, "properties.json", indent=True)

    set_seed(seed + 1)
    X, Y, XX, YY, ZZ = io_2d(0, order, 0, order, sparse=sparse)
    for i in range(ZZ.shape[0]):
        for j in range(ZZ.shape[1]):
            ZZ[i, j] = I(F(XX[i, j]) + F(YY[i, j]))
    d = {"X": X, "Y": Y, "Z": ZZ}
    save_pickle(d, folder, "add.pkl")

    set_seed(seed + 2)
    X, Y, XX, YY, ZZ = io_2d(0, order, 0, order, sparse=sparse)
    for i in range(ZZ.shape[0]):
        for j in range(ZZ.shape[1]):
            ZZ[i, j] = I(F(XX[i, j]) - F(YY[i, j]))
    d = {"X": X, "Y": Y, "Z": ZZ}
    save_pickle(d, folder, "subtract.pkl")

    set_seed(seed + 3)
    X, Y, XX, YY, ZZ = io_2d(0, order, 0, order, sparse=sparse)
    for i in range(ZZ.shape[0]):
        for j in range(ZZ.shape[1]):
            ZZ[i, j] = I(F(XX[i, j]) * F(YY[i, j]))
    d = {"X": X, "Y": Y, "Z": ZZ}
    save_pickle(d, folder, "multiply.pkl")

    set_seed(seed + 4)
    X, Y, XX, YY, ZZ = io_2d(0, order, -order - 2, order + 3, sparse=sparse)
    for i in range(ZZ.shape[0]):
        for j in range(ZZ.shape[1]):
            ZZ[i, j] = I(F(XX[i, j]) * YY[i, j])
    d = {"X": X, "Y": Y, "Z": ZZ}
    save_pickle(d, folder, "scalar_multiply.pkl")

    set_seed(seed + 5)
    X, Y, XX, YY, ZZ = io_2d(0, order, 1, order, sparse=sparse)
    for i in range(ZZ.shape[0]):
        for j in range(ZZ.shape[1]):
            ZZ[i, j] = I(F(XX[i, j]) / F(YY[i, j]))
    d = {"X": X, "Y": Y, "Z": ZZ}
    save_pickle(d, folder, "divide.pkl")

    set_seed(seed + 6)
    X, Z = io_1d(0, order, sparse=sparse)
    for i in range(X.shape[0]):
        Z[i] = I(-F(X[i]))
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "additive_inverse.pkl")

    set_seed(seed + 7)
    X, Z = io_1d(1, order, sparse=sparse)
    for i in range(X.shape[0]):
        Z[i] = I(1 / F(X[i]))
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "multiplicative_inverse.pkl")

    set_seed(seed + 8)
    X, Y, XX, YY, ZZ = io_2d(1, order, -order - 2, order + 3, sparse=sparse)
    for i in range(ZZ.shape[0]):
        for j in range(ZZ.shape[1]):
            ZZ[i, j] = I(F(XX[i, j])**YY[i, j])
    d = {"X": X, "Y": Y, "Z": ZZ}
    save_pickle(d, folder, "power.pkl")

    set_seed(seed + 9)
    X, Z = io_1d(1, order, sparse=sparse)
    for i in range(Z.shape[0]):
        try:
            Z[i] = I(field.fetch_int(X[i]).log(alpha))
        except:
            Z[i] = I(log(F(X[i]), alpha))
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "log.pkl")

    set_seed(seed + 10)
    X, Z = io_1d(0, order, sparse=sparse)
    for i in range(X.shape[0]):
        Z[i] = int(F(X[i]).additive_order())
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "additive_order.pkl")

    set_seed(seed + 11)
    X, Z = io_1d(1, order, sparse=sparse)
    for i in range(X.shape[0]):
        Z[i] = int(F(X[i]).multiplicative_order())
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "multiplicative_order.pkl")

    set_seed(seed + 12)
    X, _ = io_1d(0, order, sparse=sparse)
    Z = []
    for i in range(len(X)):
        x = F(X[i])
        p = x.charpoly()
        z = poly_to_list(p)
        Z.append(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "characteristic_poly_element.pkl")

    set_seed(seed + 13)
    shapes = [(2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]
    X = []
    Z = []
    for i in range(len(shapes)):
        x = randint_matrix(0, order, shapes[i])
        X.append(x)
        x = matrix(FIELD, [[F(e) for e in row] for row in x])
        p = x.charpoly()
        z = poly_to_list(p)
        Z.append(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "characteristic_poly_matrix.pkl")

    set_seed(seed + 14)
    X, _ = io_1d(0, order, sparse=sparse)
    Z = []
    for i in range(len(X)):
        x = F(X[i])
        p = x.minpoly()
        z = poly_to_list(p)
        Z.append(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "minimal_poly_element.pkl")

    # set_seed(seed + 15)
    # shapes = [(2,2), (3,3), (4,4), (5,5), (6,6)]
    # X = []
    # Z = []
    # for i in range(len(shapes)):
    #     x = randint_matrix(0, order, shapes[i])
    #     X.append(x)
    #     x = matrix(FIELD, [[F(e) for e in row] for row in x])
    #     p = x.minpoly()
    #     z = np.array([I(e) for e in p.list()[::-1]], dtype=dtype).tolist()
    #     z = z if z != [] else [0]
    #     Z.append(z)
    # d = {"X": X, "Z": Z}
    # save_pickle(d, folder, "minimal_poly_matrix.pkl")

    set_seed(seed + 16)
    X, Z = io_1d(0, order, sparse=sparse)
    for i in range(X.shape[0]):
        z = F(X[i]).trace()
        Z[i] = int(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "field_trace.pkl")

    set_seed(seed + 17)
    X, Z = io_1d(0, order, sparse=sparse)
    for i in range(X.shape[0]):
        z = F(X[i]).norm()
        Z[i] = int(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "field_norm.pkl")

    ###############################################################################
    # Linear algebra
    ###############################################################################

    set_seed(seed + 201)
    X_shapes = [(2, 2), (2, 3), (3, 2), (3, 3), (3, 4)]
    Y_shapes = [(2, 2), (3, 3), (2, 4), (3, 3), (4, 5)]
    X = []
    Y = []
    Z = []
    for i in range(len(shapes)):
        x = randint_matrix(0, order, X_shapes[i])
        y = randint_matrix(0, order, Y_shapes[i])
        X.append(x)
        Y.append(y)
        x = matrix(FIELD, [[F(e) for e in row] for row in x])
        y = matrix(FIELD, [[F(e) for e in row] for row in y])
        z = x * y
        z = np.array([[I(e) for e in row] for row in z], dtype)
        Z.append(z)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "matrix_multiply.pkl")

    set_seed(seed + 202)
    shapes = [(2, 2), (2, 3), (3, 2), (3, 3), (3, 4)]
    X = []
    Z = []
    for i in range(len(shapes)):
        x = randint_matrix(0, order, shapes[i])
        X.append(x)
        x = matrix(FIELD, [[F(e) for e in row] for row in x])
        z = x.rref()
        z = np.array([[I(e) for e in row] for row in z], dtype)
        Z.append(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "row_reduce.pkl")

    set_seed(seed + 203)
    shapes = [(2, 2), (2, 3), (3, 2), (3, 3), (3, 4), (4, 3), (4, 4), (4, 5),
              (5, 4), (5, 5), (5, 6), (6, 5), (6, 6)]
    X = []
    L = []
    U = []
    for i in range(len(shapes)):
        while True:
            # Ensure X has a PLU decomposition with P = I, which means it has an LU decomposition
            x = randint_matrix(0, order, shapes[i])
            x_orig = x.copy()
            x = matrix(FIELD, [[F(e) for e in row] for row in x])
            p, l, u = x.LU()
            if p == matrix.identity(FIELD, shapes[i][0]):
                break
        X.append(x_orig)
        l = np.array([[I(e) for e in row] for row in l], dtype)
        u = np.array([[I(e) for e in row] for row in u], dtype)
        L.append(l)
        U.append(u)
    d = {"X": X, "L": L, "U": U}
    save_pickle(d, folder, "lu_decompose.pkl")

    set_seed(seed + 204)
    shapes = [(2, 2), (2, 3), (3, 2), (3, 3), (3, 4), (4, 3), (4, 4), (4, 5),
              (5, 4), (5, 5), (5, 6), (6, 5), (6, 6)]
    X = []
    L = []
    U = []
    P = []
    for i in range(len(shapes)):
        x = randint_matrix(0, order, shapes[i])
        X.append(x)
        x = matrix(FIELD, [[F(e) for e in row] for row in x])
        p, l, u = x.LU()
        p = np.array([[I(e) for e in row] for row in p], dtype)
        l = np.array([[I(e) for e in row] for row in l], dtype)
        u = np.array([[I(e) for e in row] for row in u], dtype)
        P.append(p)
        L.append(l)
        U.append(u)
    d = {"X": X, "P": P, "L": L, "U": U}
    save_pickle(d, folder, "plu_decompose.pkl")

    set_seed(seed + 205)
    shapes = [(2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]
    X = []
    Z = []
    for i in range(len(shapes)):
        while True:
            x = randint_matrix(0, order, shapes[i])
            x_orig = x.copy()
            x = matrix(FIELD, [[F(e) for e in row] for row in x])
            if x.rank() == shapes[i][0]:
                break
        X.append(x_orig)
        z = x.inverse()
        z = np.array([[I(e) for e in row] for row in z], dtype)
        Z.append(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "matrix_inverse.pkl")

    set_seed(seed + 206)
    shapes = [(2, 2), (2, 2), (2, 2), (3, 3), (3, 3), (3, 3), (4, 4), (4, 4),
              (4, 4), (5, 5), (5, 5), (5, 5), (6, 6), (6, 6), (6, 6)]
    X = []
    Z = []
    for i in range(len(shapes)):
        x = randint_matrix(0, order, shapes[i])
        X.append(x)
        x = matrix(FIELD, [[F(e) for e in row] for row in x])
        z = I(x.determinant())
        Z.append(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "matrix_determinant.pkl")

    set_seed(seed + 207)
    shapes = [(2, 2), (2, 2), (2, 2), (3, 3), (3, 3), (3, 3), (4, 4), (4, 4),
              (4, 4), (5, 5), (5, 5), (5, 5), (6, 6), (6, 6), (6, 6)]
    X = []
    Y = []
    Z = []
    for i in range(len(shapes)):
        while True:
            x = randint_matrix(0, order, shapes[i])
            x_orig = x.copy()
            x = matrix(FIELD, [[F(e) for e in row] for row in x])
            if x.rank() == shapes[i][0]:
                break
        X.append(x_orig)
        y = randint_matrix(0, order, shapes[i][1])  # 1-D vector
        Y.append(y)
        y = vector(FIELD, [F(e) for e in y])
        z = x.solve_right(y)
        z = np.array([I(e) for e in z], dtype)
        Z.append(z)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "matrix_solve.pkl")

    set_seed(seed + 208)
    shapes = [(2, 2), (2, 3), (2, 4), (3, 2), (4, 2), (3, 3)]
    X = []
    Z = []
    for i in range(len(shapes)):
        deg = shapes[i][1]  # The degree of the vector space

        # Random matrix
        x = randint_matrix(0, order, shapes[i])
        X.append(x)
        x = matrix(FIELD, [[F(e) for e in row] for row in x])
        z = x.row_space()
        if z.dimension() == 0:
            z = randint_matrix(0, 1, (0, deg))
        else:
            z = z.basis_matrix()
            z = np.array([[I(e) for e in row] for row in z], dtype)
        Z.append(z)

        # Reduce the row space by 1 by copying the 0th row to the jth row
        for j in range(1, shapes[i][0]):
            x = copy(x)
            x[j, :] = F(random.randint(0, order - 1)) * x[0, :]

            z = x.row_space()
            if z.dimension() == 0:
                z = randint_matrix(0, 1, (0, deg))
            else:
                z = z.basis_matrix()
                z = np.array([[I(e) for e in row] for row in z], dtype)
            X.append(np.array([[I(e) for e in row] for row in x], dtype))
            Z.append(z)

        # Zero matrix
        x = copy(x)
        x[:] = F(0)
        z = x.row_space()
        if z.dimension() == 0:
            z = randint_matrix(0, 1, (0, deg))
        else:
            z = z.basis_matrix()
            z = np.array([[I(e) for e in row] for row in z], dtype)
        X.append(np.array([[I(e) for e in row] for row in x], dtype))
        Z.append(z)

    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "row_space.pkl")

    set_seed(seed + 209)
    shapes = [(2, 2), (2, 3), (2, 4), (3, 2), (4, 2), (3, 3)]
    X = []
    Z = []
    for i in range(len(shapes)):
        deg = shapes[i][0]  # The degree of the vector space

        # Random matrix
        x = randint_matrix(0, order, shapes[i])
        X.append(x)
        x = matrix(FIELD, [[F(e) for e in row] for row in x])
        z = x.column_space()
        if z.dimension() == 0:
            z = randint_matrix(0, 1, (0, deg))
        else:
            z = z.basis_matrix()
            z = np.array([[I(e) for e in row] for row in z], dtype)
        Z.append(z)

        # Reduce the column space by 1 by copying the 0th column to the jth column
        for j in range(1, shapes[i][1]):
            x = copy(x)
            x[:, j] = F(random.randint(0, order - 1)) * x[:, 0]

            z = x.column_space()
            if z.dimension() == 0:
                z = randint_matrix(0, 1, (0, deg))
            else:
                z = z.basis_matrix()
                z = np.array([[I(e) for e in row] for row in z], dtype)
            X.append(np.array([[I(e) for e in row] for row in x], dtype))
            Z.append(z)

        # Zero matrix
        x = copy(x)
        x[:] = F(0)
        z = x.column_space()
        if z.dimension() == 0:
            z = randint_matrix(0, 1, (0, deg))
        else:
            z = z.basis_matrix()
            z = np.array([[I(e) for e in row] for row in z], dtype)
        X.append(np.array([[I(e) for e in row] for row in x], dtype))
        Z.append(z)

    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "column_space.pkl")

    set_seed(seed + 210)
    shapes = [(2, 2), (2, 3), (2, 4), (3, 2), (4, 2), (3, 3)]
    X = []
    Z = []
    for i in range(len(shapes)):
        deg = shapes[i][0]  # The degree of the vector space

        # Random matrix
        x = randint_matrix(0, order, shapes[i])
        X.append(x)
        x = matrix(FIELD, [[F(e) for e in row] for row in x])
        z = x.left_kernel()
        if z.dimension() == 0:
            z = randint_matrix(0, 1, (0, deg))
        else:
            z = z.basis_matrix()
            z = np.array([[I(e) for e in row] for row in z], dtype)
        Z.append(z)

        # Reduce the left null space by 1 by copying the 0th row to the jth row
        for j in range(1, shapes[i][0]):
            x = copy(x)
            x[j, :] = F(random.randint(0, order - 1)) * x[0, :]

            z = x.left_kernel()
            if z.dimension() == 0:
                z = randint_matrix(0, 1, (0, deg))
            else:
                z = z.basis_matrix()
                z = np.array([[I(e) for e in row] for row in z], dtype)
            X.append(np.array([[I(e) for e in row] for row in x], dtype))
            Z.append(z)

        # Zero matrix
        x = copy(x)
        x[:] = F(0)
        z = x.left_kernel()
        if z.dimension() == 0:
            z = randint_matrix(0, 1, (0, deg))
        else:
            z = z.basis_matrix()
            z = np.array([[I(e) for e in row] for row in z], dtype)
        X.append(np.array([[I(e) for e in row] for row in x], dtype))
        Z.append(z)

    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "left_null_space.pkl")

    set_seed(seed + 211)
    shapes = [(2, 2), (2, 3), (2, 4), (3, 2), (4, 2), (3, 3)]
    X = []
    Z = []
    for i in range(len(shapes)):
        deg = shapes[i][1]  # The degree of the vector space

        # Random matrix
        x = randint_matrix(0, order, shapes[i])
        X.append(x)
        x = matrix(FIELD, [[F(e) for e in row] for row in x])
        z = x.right_kernel()
        if z.dimension() == 0:
            z = randint_matrix(0, 1, (0, deg))
        else:
            z = z.basis_matrix()
            z = np.array([[I(e) for e in row] for row in z], dtype)
        Z.append(z)

        # Reduce the null space by 1 by copying the 0th column to the jth column
        for j in range(1, shapes[i][1]):
            x = copy(x)
            x[:, j] = F(random.randint(0, order - 1)) * x[:, 0]

            z = x.right_kernel()
            if z.dimension() == 0:
                z = randint_matrix(0, 1, (0, deg))
            else:
                z = z.basis_matrix()
                z = np.array([[I(e) for e in row] for row in z], dtype)
            X.append(np.array([[I(e) for e in row] for row in x], dtype))
            Z.append(z)

        # Zero matrix
        x = copy(x)
        x[:] = F(0)
        z = x.right_kernel()
        if z.dimension() == 0:
            z = randint_matrix(0, 1, (0, deg))
        else:
            z = z.basis_matrix()
            z = np.array([[I(e) for e in row] for row in z], dtype)
        X.append(np.array([[I(e) for e in row] for row in x], dtype))
        Z.append(z)

    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "null_space.pkl")

    ###############################################################################
    # Polynomial arithmetic
    ###############################################################################
    folder = os.path.join(PATH, "polys", "data", sub_folder)
    if os.path.exists(folder):
        shutil.rmtree(folder)
    os.mkdir(folder)

    MIN_COEFFS = 1
    MAX_COEFFS = 12

    set_seed(seed + 101)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Z = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        y = list_to_poly(Y[i])
        z = x + y
        z = poly_to_list(z)
        Z.append(z)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "add.pkl")

    set_seed(seed + 102)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Z = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        y = list_to_poly(Y[i])
        z = x - y
        z = poly_to_list(z)
        Z.append(z)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "subtract.pkl")

    set_seed(seed + 103)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Z = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        y = list_to_poly(Y[i])
        z = x * y
        z = poly_to_list(z)
        Z.append(z)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "multiply.pkl")

    set_seed(seed + 104)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Y = [random.randint(1, 2 * characteristic) for i in range(20)]
    Z = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        y = Y[i]
        z = x * y
        z = poly_to_list(z)
        Z.append(z)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "scalar_multiply.pkl")

    set_seed(seed + 105)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    # Add some specific polynomial types
    X.append([0]), Y.append(random_coeffs(0, order, MIN_COEFFS,
                                          MAX_COEFFS))  # 0 / y
    X.append(random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS // 2)), Y.append(
        random_coeffs(0, order, MAX_COEFFS // 2,
                      MAX_COEFFS))  # x / y with x.degree < y.degree
    X.append(random_coeffs(0, order, 2, MAX_COEFFS)), Y.append(
        random_coeffs(0, order, 1, 2))  # x / y with y.degree = 0
    Q = []
    R = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        y = list_to_poly(Y[i])
        q = x // y
        r = x % y
        q = poly_to_list(q)
        Q.append(q)
        r = poly_to_list(r)
        R.append(r)
    d = {"X": X, "Y": Y, "Q": Q, "R": R}
    save_pickle(d, folder, "divmod.pkl")

    set_seed(seed + 106)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(4)]
    X.append(random_coeffs(0, order, 1, 2))
    Y = [0, 1, 2, 3]
    Z = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        ZZ = []
        for j in range(len(Y)):
            y = Y[j]
            z = x**y
            z = poly_to_list(z)
            ZZ.append(z)
        Z.append(ZZ)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "power.pkl")

    set_seed(seed + 107)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Y = arange(0, order, sparse=sparse)
    Z = np.array(np.zeros((len(X), len(Y))), dtype=dtype)
    for i in range(len(X)):
        for j in range(len(Y)):
            x = list_to_poly(X[i])
            y = F(Y[j])
            z = x(y)
            Z[i, j] = I(z)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "evaluate.pkl")

    set_seed(seed + 108)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Y = [randint_matrix(0, order, (2, 2)) for i in range(20)]
    Z = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        y = matrix(FIELD, [[F(e) for e in row] for row in Y[i]])
        z = x(y)
        z = np.array([[I(e) for e in row] for row in z], dtype)
        Z.append(z)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "evaluate_matrix.pkl")

    ###############################################################################
    # Polynomial arithmetic methods
    ###############################################################################

    set_seed(seed + 301)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Z = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        z = x.reverse()
        z = poly_to_list(z)
        Z.append(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "reverse.pkl")

    set_seed(seed + 302)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    R = []
    M = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        roots = x.roots()
        RR, MM = [], []
        for root in roots:
            r = root[0]
            m = root[1]
            RR.append(I(r))
            MM.append(int(m))
        idxs = np.argsort(RR)  # Sort by ascending roots
        RR = (np.array(RR, dtype=dtype)[idxs]).tolist()
        MM = (np.array(MM, dtype=dtype)[idxs]).tolist()
        R.append(RR)
        M.append(MM)
    d = {"X": X, "R": R, "M": M}
    save_pickle(d, folder, "roots.pkl")

    set_seed(seed + 303)
    X = [
        random_coeffs(0, order, 2 * FIELD.degree(), 6 * FIELD.degree())
        for i in range(20)
    ]
    Y = [
        1,
    ] * 10 + [random.randint(2,
                             FIELD.degree() + 1) for i in range(10)]
    Z = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        z = x.derivative(Y[i])
        z = poly_to_list(z)
        Z.append(z)
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "derivative.pkl")

    ###############################################################################
    # Polynomial arithmetic functions
    ###############################################################################

    set_seed(seed + 401)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    D = []
    S = []
    T = []
    for i in range(len(X)):
        x = list_to_poly(X[i])
        y = list_to_poly(Y[i])
        d, s, t = xgcd(x, y)
        d = poly_to_list(d)
        s = poly_to_list(s)
        t = poly_to_list(t)
        D.append(d)
        S.append(s)
        T.append(t)
    d = {"X": X, "Y": Y, "D": D, "S": S, "T": T}
    save_pickle(d, folder, "egcd.pkl")

    set_seed(seed + 402)
    X = []
    Z = []
    for i in range(20):
        XX = [
            random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS)
            for i in range(random.randint(2, 5))
        ]
        X.append(XX)
        xx = [list_to_poly(XXi) for XXi in XX]
        z = lcm(xx)
        z = poly_to_list(z)
        Z.append(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "lcm.pkl")

    set_seed(seed + 403)
    X = []
    Z = []
    for i in range(20):
        XX = [
            random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS)
            for i in range(random.randint(2, 5))
        ]
        X.append(XX)
        xx = [list_to_poly(XXi) for XXi in XX]
        z = prod(xx)
        z = poly_to_list(z)
        Z.append(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "prod.pkl")

    set_seed(seed + 404)
    X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    E = [random.randint(2, 10) for i in range(20)]
    M = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
    Z = []
    for i in range(20):
        x = list_to_poly(X[i])
        e = E[i]
        m = list_to_poly(M[i])
        z = (x**e) % m
        z = poly_to_list(z)
        Z.append(z)
    d = {"X": X, "E": E, "M": M, "Z": Z}
    save_pickle(d, folder, "modular_power.pkl")

    set_seed(seed + 405)
    X = [
        0,
    ] * 20  # The remainder
    Y = [
        0,
    ] * 20  # The modulus
    Z = [
        0,
    ] * 20  # The solution
    for i in range(20):
        n = random.randint(2, 4)  # The number of polynomials
        x, y = [], []
        for j in range(n):
            d = random.randint(3, 5)
            x.append(random_coeffs(0, order, d, d + 1))
            y.append(random_coeffs(
                0, order, d + 1, d +
                2))  # Ensure modulus degree is greater than remainder degree
        X[i] = x
        Y[i] = y
        try:
            x = [list_to_poly(xx) for xx in x]
            y = [list_to_poly(yy) for yy in y]
            z = crt(x, y)
            Z[i] = poly_to_list(z)
        except:
            Z[i] = None
    d = {"X": X, "Y": Y, "Z": Z}
    save_pickle(d, folder, "crt.pkl")

    ###############################################################################
    # Special polynomials
    ###############################################################################

    set_seed(seed + 501)
    X = [random_coeffs(0, order, 1, 6) for _ in range(20)]
    Z = [
        False,
    ] * len(X)
    for i in range(len(X)):
        if random.choice(["one", "other"]) == "one":
            X[i][0] = 1
        x = list_to_poly(X[i])
        z = x.is_monic()
        Z[i] = bool(z)
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "is_monic.pkl")

    set_seed(seed + 502)
    IS = []
    IS_NOT = []
    if order <= 2**16:
        while len(IS) < 10:
            x = random_coeffs(0, order, 1, 6)
            f = list_to_poly(x)
            if f.is_irreducible():
                IS.append(x)
        while len(IS_NOT) < 10:
            x = random_coeffs(0, order, 1, 6)
            f = list_to_poly(x)
            if not f.is_irreducible():
                IS_NOT.append(x)
    d = {"IS": IS, "IS_NOT": IS_NOT}
    save_pickle(d, folder, "is_irreducible.pkl")

    set_seed(seed + 503)
    IS = []
    IS_NOT = []
    if order <= 2**16:
        while len(IS) < 10:
            x = random_coeffs(0, order, 1, 6)
            f = list_to_poly(x)
            # f = f / f.coefficients()[-1]  # Make monic
            # assert f.is_monic()
            if f.degree() == 1 and f.coefficients(sparse=False)[0] == 0:
                continue  # For some reason `is_primitive()` crashes on f(x) = a*x
            if not f.is_irreducible():
                continue  # Want to find an irreducible polynomial that is also primitive
            if f.is_primitive():
                IS.append(x)
        while len(IS_NOT) < 10:
            x = random_coeffs(0, order, 1, 6)
            f = list_to_poly(x)
            # f = f / f.coefficients()[-1]  # Make monic
            # assert f.is_monic()
            if f.degree() == 1 and f.coefficients(sparse=False)[0] == 0:
                continue  # For some reason `is_primitive()` crashes on f(x) = a*x
            if not f.is_irreducible():
                continue  # Want to find an irreducible polynomial that is not primitive
            if not f.is_primitive():
                IS_NOT.append(x)
    d = {"IS": IS, "IS_NOT": IS_NOT}
    save_pickle(d, folder, "is_primitive.pkl")

    set_seed(seed + 504)
    if order <= 2**16:
        X = [random_coeffs(0, order, 1, 6) for _ in range(20)]
        Z = [
            False,
        ] * len(X)
        for i in range(len(X)):
            x = list_to_poly(X[i])
            z = x.is_squarefree()
            Z[i] = bool(z)
    else:
        X = []
        Z = []
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "is_square_free.pkl")
Пример #17
0
 def so3_matrix_for_path(self, p):
     if p:
         return prod([self.so3_matrix_for_edge(e) for e in p[::-1]])
     else:
         RF = self.vertex_gram_matrices[0].base_ring()
         return matrix.identity(RF, 3)
Пример #18
0
 def _add_initial_tile(self):
     tet = self.mcomplex.Tetrahedra[0]
     CIF = tet.ShapeParameters[simplex.E01].parent()
     m = matrix.identity(CIF, 2)
     return self.add_tile(m)