def integral_cuspidal_subspace(self): """ In certatain cases this might return the integral structure of the cuspidal subspace. This code is mainly a way to compute the integral structe faster than sage does now. It returns None if it cannot find the integral subspace. """ if self.verbose: tm = cputime(); mem = get_memory_usage(); print "Int struct start" #This code is the same as the firs part of self.M.integral_structure G = set([i for i, _ in self.M._mod2term]) G = list(G) G.sort() #if there is a two term relation between two manin symbols we only need one of the two #so that's why we only use elements from G instead of all manin symbols. if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "G" B = self.M._manin_gens_to_basis.matrix_from_rows(list(G)).sparse_matrix() if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "B" #The collums of B now span self.M.integral_structure as ZZ-module B, d = B._clear_denom() if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Clear denom" if d == 1: #for explanation see d == 2 assert len(set([B.nonzero_positions_in_row(i)[0] for i in xrange(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 1])) == B.ncols(), "B doesn't contain the Identity" if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Check Id" ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1) if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis" elif d == 2: #in this case the matrix B will contain 2*Id as a minor this allows us to compute the hermite normal form of B in a very efficient way. This will give us the integral basis ZZbasis. #if it turns out to be nessecarry this can be generalized to the case d%4==2 if we don't mind to only get the right structure localized at 2 assert len(set([B.nonzero_positions_in_row(i)[0] for i in xrange(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 2])) == B.ncols(), "B doesn't contain 2*Identity" if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Check 2*Id" E = matrix_modp(B,sparse=True) if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "matmodp" E = E.echelon_form() if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "echelon" ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1) for (pivot_row, pivot_col) in zip(E.pivot_rows(), E.pivots()): for j in E.nonzero_positions_in_row(pivot_row): ZZbasis[pivot_col, j] = QQ(1) / 2 if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis" else: return None #now we compute the integral kernel of the boundary map with respect to the integral basis. This will give us the integral cuspidal submodule. boundary_matrix = self.M.boundary_map().matrix() if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "Boundary matrix" ZZboundary_matrix=(ZZbasis*boundary_matrix).change_ring(ZZ) if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZBoundary matrix" left_kernel_matrix=ZZboundary_matrix.transpose().dense_matrix()._right_kernel_matrix(algorithm='pari') if type(left_kernel_matrix)==tuple: left_kernel_matrix=left_kernel_matrix[1] if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "kernel matrix" ZZcuspidal_basis=left_kernel_matrix*ZZbasis if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "ZZkernel matrix" assert ZZcuspidal_basis.change_ring(QQ).echelon_form()==self.S.basis_matrix() , "the calculated integral basis does not span the right QQ vector space" # a little sanity check. This shows that the colums of ZZcuspidal_basis really span the right QQ vectorspace if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "check" #finally create the sub-module, we delibarately do this as a QQ vector space with custom basis, because this is faster then dooing the calculations over ZZ since sage will then use a slow hermite normal form algorithm. ambient_module=VectorSpace(QQ,ZZcuspidal_basis.ncols()) int_struct = ambient_module.submodule_with_basis(ZZcuspidal_basis.rows()) if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "finnished" return int_struct
def integral_cuspidal_subspace(self): """ In certatain cases this might return the integral structure of the cuspidal subspace. This code is mainly a way to compute the integral structe faster than sage does now. It returns None if it cannot find the integral subspace. """ if self.verbose: tm = cputime(); mem = get_memory_usage(); print("Int struct start") #This code is the same as the firs part of self.M.integral_structure G = set([i for i, _ in self.M._mod2term]) G = list(G) G.sort() #if there is a two term relation between two manin symbols we only need one of the two #so that's why we only use elements from G instead of all manin symbols. if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "G") B = self.M._manin_gens_to_basis.matrix_from_rows(list(G)).sparse_matrix() if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "B") #The collums of B now span self.M.integral_structure as ZZ-module B, d = B._clear_denom() if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Clear denom") if d == 1: #for explanation see d == 2 assert len(set([B.nonzero_positions_in_row(i)[0] for i in range(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 1])) == B.ncols(), "B doesn't contain the Identity" if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Check Id") ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1) if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis") elif d == 2: #in this case the matrix B will contain 2*Id as a minor this allows us to compute the hermite normal form of B in a very efficient way. This will give us the integral basis ZZbasis. #if it turns out to be nessecarry this can be generalized to the case d%4==2 if we don't mind to only get the right structure localized at 2 assert len(set([B.nonzero_positions_in_row(i)[0] for i in range(B.nrows()) if len(B.nonzero_positions_in_row(i)) == 1 and B[i, B.nonzero_positions_in_row(i)[0]] == 2])) == B.ncols(), "B doesn't contain 2*Identity" if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Check 2*Id") E = matrix_modp(B,sparse=True) if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "matmodp") E = E.echelon_form() if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "echelon") ZZbasis = MatrixSpace(QQ, B.ncols(), sparse=True)(1) for (pivot_row, pivot_col) in zip(E.pivot_rows(), E.pivots()): for j in E.nonzero_positions_in_row(pivot_row): ZZbasis[pivot_col, j] = QQ(1) / 2 if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZbasis") else: return None #now we compute the integral kernel of the boundary map with respect to the integral basis. This will give us the integral cuspidal submodule. boundary_matrix = self.M.boundary_map().matrix() if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "Boundary matrix") ZZboundary_matrix=(ZZbasis*boundary_matrix).change_ring(ZZ) if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZBoundary matrix") left_kernel_matrix=ZZboundary_matrix.transpose().dense_matrix()._right_kernel_matrix(algorithm='pari') if type(left_kernel_matrix)==tuple: left_kernel_matrix=left_kernel_matrix[1] if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "kernel matrix") ZZcuspidal_basis=left_kernel_matrix*ZZbasis if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "ZZkernel matrix") assert ZZcuspidal_basis.change_ring(QQ).echelon_form()==self.S.basis_matrix() , "the calculated integral basis does not span the right QQ vector space" # a little sanity check. This shows that the colums of ZZcuspidal_basis really span the right QQ vectorspace if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "check") #finally create the sub-module, we delibarately do this as a QQ vector space with custom basis, because this is faster then dooing the calculations over ZZ since sage will then use a slow hermite normal form algorithm. ambient_module=VectorSpace(QQ,ZZcuspidal_basis.ncols()) int_struct = ambient_module.submodule_with_basis(ZZcuspidal_basis.rows()) if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "finnished") return int_struct
def _get_labels(M, x, rows, L): from sage.all import VectorSpace, Set, Matrix # If non-central, then this is true iff not intersecting. not_e1 = lambda v: list(v)[1:] != [0] * (len(v) - 1) # Determine new hyperplanes and group like rows together. V = VectorSpace(M.base_ring(), M.ncols()) lines = [] labels = [] for r in range(M.nrows()): v = M[r] is_new = not_e1(v) i = 0 while i < len(lines) and is_new: if v in V.subspace([lines[i]]): is_new = False labels[i] = labels[i].union(Set([r])) else: i += 1 if is_new: lines.append(v) labels.append(Set([r])) # Adjust the labels because we are missing rows. fix_sets = lambda F: lambda S: Set(list(map(lambda s: F(s), S))) for k in rows: adjust = lambda i: i + (k <= i) * 1 labels = list(map(fix_sets(adjust), labels)) labels = [Set(rows)] + labels # Adjust the row labels to hyperplane labels HL = L.hyperplane_labels A = L.hyperplane_arrangement HL_lab = lambda i: list(filter(lambda j: HL[j] == A[i], HL.keys()))[0] labels = list(map(fix_sets(HL_lab), labels)) # Get the new hyperplanes FL = L.flat_labels new_hyp = [labels[k].union(labels[0]) for k in range(1, len(labels))] P = L.poset flat = lambda S: list(filter(lambda j: FL[j] == S, P.upper_covers(x)))[0] new_hyp = list(map(flat, new_hyp)) def last_adj(S): l_hyp = labels[1:] T = S.difference(labels[0]) new_T = Set([]) for k in range(len(l_hyp)): if l_hyp[k].issubset(T): new_T = new_T.union(Set([new_hyp[k]])) return new_T return Matrix(lines), last_adj, { new_hyp[i]: i for i in range(len(new_hyp)) }
def monics(F, d, u=1): """Iterate through all degree d polynomials over F with leading coefficient u. NB Use u=1 to get monics, and u=0 to give all polys of degree <d. """ Fx = PolynomialRing(F, 'x') for v in VectorSpace(F, d): yield Fx(v.list() + [u])
def _random_ini(dop): import random from sage.all import VectorSpace, QQ ind = dop.indicial_polynomial(dop.base_ring().gen()) sl_decomp = my_shiftless_decomposition(ind) pol, shifts = random.choice(sl_decomp) expo = random.choice(pol.roots(QQbar))[0] values = { shift: tuple(VectorSpace(QQ, mult).random_element(10)) for shift, mult in shifts } return LogSeriesInitialValues(expo, values, dop)
def randomize(self, prime): assert not self.randomized MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), self.size) def random_matrix(): while True: m = MSZp.random_element() if not m.is_singular() and m.rank() == self.size: return m, m.inverse() m0, m0i = random_matrix() self.bp[0] = self.bp[0].group(MSZp, prime).mult_left(m0) for i in xrange(1, len(self.bp)): mi, mii = random_matrix() self.bp[i-1] = self.bp[i-1].group(MSZp, prime).mult_right(mii) self.bp[i] = self.bp[i].group(MSZp, prime).mult_left(mi) self.bp[-1] = self.bp[-1].group(MSZp, prime).mult_right(m0i) VSZp = VectorSpace(ZZ.residue_field(ZZ.ideal(prime)), self.size) self.s = copy(VSZp.zero()) self.s[0] = 1 self.t = copy(VSZp.zero()) self.t[len(self.t) - 1] = 1 self.m0, self.m0i = m0, m0i self.randomized = True
def random_ini(dop): import random from sage.all import VectorSpace ind = dop.indicial_polynomial(dop.base_ring().gen()) sl_decomp = my_shiftless_decomposition(ind) pol, shifts = random.choice(sl_decomp) expo = random.choice(pol.roots(QQbar))[0] expo = utilities.as_embedded_number_field_element(expo) values = {} while all(a.is_zero() for v in values.values() for a in v): values = { shift: tuple(VectorSpace(QQ, mult).random_element(10)) for shift, mult in shifts } return LogSeriesInitialValues(expo, values, dop)
def randomize(self, prime): assert not self.randomized MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), self.size) def random_matrix(): while True: m = MSZp.random_element() if not m.is_singular() and m.rank() == self.size: return m, m.inverse() m0, m0i = random_matrix() self.bp[0] = self.bp[0].group(MSZp, prime).mult_left(m0) for i in xrange(1, len(self.bp)): mi, mii = random_matrix() self.bp[i - 1] = self.bp[i - 1].group(MSZp, prime).mult_right(mii) self.bp[i] = self.bp[i].group(MSZp, prime).mult_left(mi) self.bp[-1] = self.bp[-1].group(MSZp, prime).mult_right(m0i) VSZp = VectorSpace(ZZ.residue_field(ZZ.ideal(prime)), self.size) self.s = copy(VSZp.zero()) self.s[0] = 1 self.t = copy(VSZp.zero()) self.t[len(self.t) - 1] = 1 self.m0, self.m0i = m0, m0i self.randomized = True
def __pow__(self, n, _=None): r""" Return the vector space of dimension ``n`` over this field. EXAMPLES:: sage: from pyeantic import RealEmbeddedNumberField sage: K = NumberField(x**2 - 2, 'a', embedding=sqrt(AA(2))) sage: K = RealEmbeddedNumberField(K) sage: K^3 Vector space of dimension 3 over Real Embedded Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? """ if isinstance(n, tuple): m, n = n from sage.all import MatrixSpace return MatrixSpace(self, m, n) else: from sage.all import VectorSpace return VectorSpace(self, n)
def _para_intersection_poset(A): from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace from sage.all import exists, flatten, Set, QQ, VectorSpace, Poset from .Globals import __SANITY N = _N K = A.base_ring() whole_space = AffineSubspace(0, VectorSpace(K, A.dimension())) # L is the ranked list of affine subspaces in L(A). L = [[whole_space], list(map(lambda H: H._affine_subspace(), A))] # hyp_cont is the ranked list describing which hyperplanes contain the # corresponding intersection. hyp_cont = [[Set([])], [Set([k]) for k in range(len(A))]] c = A.is_central() * (-1) for r in range(2, A.rank() + c + 1): print("{1}Working on elements of rank {0}".format(r, _time())) m = len(L[r - 1]) pmax = lambda k: (k + 1) * (m // N) + (k == N - 1) * (m % N) pmin = lambda k: k * (m // N) all_input = lambda k: tuple([ A, range(pmin(k), pmax(k)), hyp_cont[r - 1][pmin(k):pmax(k)], L[r - 1] [pmin(k):pmax(k)] ]) data = list( build_next([all_input(k) for k in range(N) if pmin(k) != pmax(k)])) data = _reduce(lambda x, y: x + y[1], data, []) new_lev, new_hyp = list(zip(*data)) new_lev = list(new_lev) new_hyp = list(new_hyp) i = 0 # Merge the lists down print("{0}Merging the lists from the {1} workers".format(_time(), N)) # First we check the affine spaces while i < len(new_lev): U = new_lev[i] B1 = U.linear_part().basis_matrix() p1 = U.point() j = i + 1 while j < len(new_lev): V = new_lev[j] B2 = V.linear_part().basis_matrix() p2 = V.point() if B1 == B2 and p1 == p2: new_lev = new_lev[:j] + new_lev[j + 1:] new_hyp[i] = new_hyp[i].union(new_hyp[j]) new_hyp = new_hyp[:j] + new_hyp[j + 1:] else: j += 1 i += 1 # Second we check the labels of intersection (don't want duplicates) i = 0 while i < len(new_lev): j = i + 1 while j < len(new_lev): if new_hyp[i] == new_hyp[j]: new_lev = new_lev[:j] + new_lev[j + 1:] new_hyp = new_hyp[:j] + new_hyp[j + 1:] else: j += 1 i += 1 L.append(new_lev) hyp_cont.append(new_hyp) # A silly optimization for centrals. if A.is_central() and len(A) > 1: inter = lambda X, Y: X.intersection(Y._affine_subspace()) L.append([_reduce(inter, A[1:], A[0]._affine_subspace())]) hyp_cont.append([Set(list(range(len(A))))]) L_flat = list(_reduce(lambda x, y: x + y, L, [])) hc_flat = list(_reduce(lambda x, y: x + y, hyp_cont, [])) # Sanity checks if __SANITY: print("{0}Running sanity check".format(_time())) assert len(L_flat) == len(hc_flat) for i in range(len(hc_flat)): for j in range(i + 1, len(hc_flat)): assert hc_flat[i] != hc_flat[j], "{0} vs {1}".format(i, j) for i in range(len(L_flat)): I = list(map(lambda x: A[x], hc_flat[i])) U = _reduce(lambda x, y: x.intersection(y._affine_subspace()), I, whole_space) assert U == L_flat[i], "{0} vs {1}".format(U, L_flat[i]) print("{0}Constructing lattice of flats".format(_time())) t = {} for i in range(len(hc_flat)): t[i] = Set(list(map(lambda x: x + 1, hc_flat[i]))) cmp_fn = lambda p, q: t[p].issubset(t[q]) label_dict = {i: t[i] for i in range(len(hc_flat))} get_hyp = lambda i: A[label_dict[i].an_element() - 1] hyp_dict = {i + 1: get_hyp(i + 1) for i in range(len(A))} return [Poset((t, cmp_fn)), label_dict, hyp_dict]
def vector_to_double_char(v): assert len(v) == 2 return CHARSET[v[0]] + CHARSET[v[1]] def encrypt(msg, K): assert all(c in CHARSET for c in msg) assert len(msg) % 2 == 0 A, v = K ciphertext = "" for i in range(0, len(msg), 2): tmp = A * double_char_to_vector(msg[i:i + 2]) + v ciphertext += vector_to_double_char(tmp) return ciphertext if __name__ == '__main__': from secret import flag assert flag.startswith('kmactf') A = MatrixSpace(Fp, 2, 2).random_element() v = VectorSpace(Fp, 2).random_element() assert A.determinant() != 0 print('ciphertext =', repr(encrypt(flag, (A, v)))) # Output: # ciphertext = 'u_rm3eefa}_7det1znb{sce{qo0h7yf0b}sktse8xtr6'
def solve(vectors, goal): M = MatrixSpace(GF(2), len(vectors), len(vectors[0])) V = VectorSpace(GF(2), len(goal)) A = M(vectors) b = V(goal) return A.solve_left(b)
def __init__(self, p, congruence_type=1, sign=1, algorithm="custom", verbose=False, dump_dir=None): """ Create a Kamienny criterion object. INPUT: - `p` -- prime -- verify that there is no order p torsion over a degree `d` field - `sign` -- 1 (default),-1 or 0 -- the sign of the modular symbols space to use - ``algorithm`` -- "default" or "custom" whether to use a custom (faster) integral structure algorithm or to use the sage builtin algortihm - ``verbose`` -- bool; whether to print extra stuff while running. EXAMPLES:: sage: from mdsage import * sage: C = KamiennyCriterion(29, algorithm="custom", verbose=False); C Kamienny's Criterion for p=29 sage: C.use_custom_algorithm True sage: C.p 29 sage: C.verbose False """ self.verbose = verbose self.dump_dir = dump_dir if self.verbose: tm = cputime(); mem = get_memory_usage(); print "init" assert congruence_type == 0 or congruence_type == 1 self.congruence_type=congruence_type try: p = ZZ(p) if congruence_type==0: self.congruence_group = Gamma0(p) if congruence_type==1: self.congruence_group = GammaH(p,[-1]) except TypeError: self.congruence_group = GammaH(p.level(),[-1]+p._generators_for_H()) self.congruence_type = ("H",self.congruence_group._list_of_elements_in_H()) self.p = self.congruence_group.level() self.algorithm=algorithm self.sign=sign self.M = ModularSymbols(self.congruence_group, sign=sign) if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "modsym" self.S = self.M.cuspidal_submodule() if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "cuspsub" self.use_custom_algorithm = False if algorithm=="custom": self.use_custom_algorithm = True if self.use_custom_algorithm: int_struct = self.integral_cuspidal_subspace() if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "custom int_struct" else: int_struct = self.S.integral_structure() if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "sage int_struct" self.S_integral = int_struct v = VectorSpace(GF(2), self.S.dimension()).random_element() self.v=v if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "rand_vect" if dump_dir: v.dump(dump_dir+"/vector%s_%s" % (p,congruence_type)) if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "dump"
def __init__(self, p, congruence_type=1, sign=1, algorithm="custom", verbose=False, dump_dir=None): """ Create a Kamienny criterion object. INPUT: - `p` -- prime -- verify that there is no order p torsion over a degree `d` field - `sign` -- 1 (default),-1 or 0 -- the sign of the modular symbols space to use - ``algorithm`` -- "default" or "custom" whether to use a custom (faster) integral structure algorithm or to use the sage builtin algortihm - ``verbose`` -- bool; whether to print extra stuff while running. EXAMPLES:: sage: from mdsage import * sage: C = KamiennyCriterion(29, algorithm="custom", verbose=False); C Kamienny's Criterion for p=29 sage: C.use_custom_algorithm True sage: C.p 29 sage: C.verbose False """ self.verbose = verbose self.dump_dir = dump_dir if self.verbose: tm = cputime(); mem = get_memory_usage(); print("init") assert congruence_type == 0 or congruence_type == 1 self.congruence_type=congruence_type try: p = ZZ(p) if congruence_type==0: self.congruence_group = Gamma0(p) if congruence_type==1: self.congruence_group = GammaH(p,[-1]) except TypeError: self.congruence_group = GammaH(p.level(),[-1]+p._generators_for_H()) self.congruence_type = ("H",self.congruence_group._list_of_elements_in_H()) self.p = self.congruence_group.level() self.algorithm=algorithm self.sign=sign self.M = ModularSymbols(self.congruence_group, sign=sign) if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "modsym") self.S = self.M.cuspidal_submodule() if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "cuspsub") self.use_custom_algorithm = False if algorithm=="custom": self.use_custom_algorithm = True if self.use_custom_algorithm: int_struct = self.integral_cuspidal_subspace() if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "custom int_struct") else: int_struct = self.S.integral_structure() if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "sage int_struct") self.S_integral = int_struct v = VectorSpace(GF(2), self.S.dimension()).random_element() self.v=v if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "rand_vect") if dump_dir: v.dump(dump_dir+"/vector%s_%s" % (p,congruence_type)) if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "dump")