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
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)
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]
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
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()
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)
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)
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)])
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)])
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))
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
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
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
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")
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)
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)