def godement_sheaf(self): """ Returns the Godement sheaf of ``self``. """ g0_stalks = dict() g0_res = dict() for p in self._domain_poset.list(): g0_stalks[p] = sum(self._stalk_dict[x] for x in self._domain_poset.order_filter([p])) for relation in self._domain_poset.cover_relations(): frombase = sorted(self._domain_poset.order_filter([relation[0]])) tobase = sorted(self._domain_poset.order_filter([relation[1]])) rows = [] for row in tobase: m = self._stalk_dict[row] blocks = [] for x in frombase: if x == row: blocks.append(identity_matrix(m)) else: blocks.append(Matrix(m, self._stalk_dict[x])) rows.append(blocks) g0_res[tuple(relation)] = block_matrix(rows, subdivide=False) G0 = LocallyFreeSheafFinitePoset(g0_stalks, g0_res, self._base_ring, self._domain_poset) hom = Hom(self, G0) eps_dict = dict() for p in self._domain_poset.list(): rows = [] for x in sorted(self._domain_poset.order_filter([p])): if x == p: rows.append([identity_matrix(self._base_ring, self._stalk_dict[p])]) else: rows.append([self.restriction(p, x).matrix()]) eps_dict[p] = block_matrix(rows, subdivide=False) epsilon = hom(eps_dict) return epsilon, G0
def _godement_complex_differential(self, start_base, end_base): """ Construct the differential of the godement cochain complex from the free module with basis ``start_base`` to the free module with basis ``end_base``. """ rows = [] for to_chain in end_base: blocks = [] m = self._stalk_dict[to_chain[-1]] for from_chain in start_base: n = self._stalk_dict[from_chain[-1]] if all(x in to_chain for x in from_chain): for point in to_chain: if point not in from_chain: index = to_chain.index(point) sign = 1 if index % 2 == 0 else - 1 if index != len(to_chain) - 1: blocks.append(sign*identity_matrix(self._base_ring, m)) else: mat = self.restriction(from_chain[-1], point).matrix() blocks.append(sign*mat) break else: blocks.append(Matrix(self._base_ring, m, n)) rows.append(blocks) return block_matrix(rows, subdivide=False)
def minor(self, contractions=None, deletions=None): contractions = list(contractions) if contractions else [] deletions = list(deletions) if deletions else [] new_groundset = [e for e in self._E if e not in contractions+deletions] A2 = copy.copy(self._A[:, [self._groundset_to_index[e] for e in new_groundset]]) Q2 = block_matrix(ZZ, [[self._A[:, [self._groundset_to_index[e] for e in contractions]], self._Q]]) return ToricArithmeticMatroid(arrangement_matrix=A2, torus_matrix=Q2, ordered_groundset=new_groundset)
def dual(self): T = block_matrix(ZZ, [[self._A[:, [self._groundset_to_index[e] for e in self._E]], self._Q]]).transpose() I = identity_matrix(ZZ, T.nrows()) # create temporary names for new groundset elements temp_elements = [-i for i in xrange(self._Q.ncols())] while len(frozenset(temp_elements).intersection(self.groundset())) > 0: temp_elements = [e-1 for e in temp_elements] M = ToricArithmeticMatroid(arrangement_matrix=I, torus_matrix=T, ordered_groundset=list(self._E)+temp_elements) return M.minor(deletions=temp_elements)
def __init__(self, R, ngens=2, names=None, index_set=None): """ Initialize self. TESTS:: sage: V = lie_conformal_algebras.BosonicGhosts(QQ) sage: TestSuite(V).run() """ try: assert (ngens > 0 and ngens % 2 == 0) except AssertionError: raise ValueError("ngens should be an even positive integer, " + "got {}".format(ngens)) latex_names = None if (names is None) and (index_set is None): from sage.misc.defaults import variable_names as varnames from sage.misc.defaults import latex_variable_names as laxnames names = varnames(ngens / 2, 'b') + varnames(ngens / 2, 'c') latex_names = tuple(laxnames(ngens/2,'b') +\ laxnames(ngens/2,'c')) + ('K',) from sage.structure.indexed_generators import \ standardize_names_index_set names, index_set = standardize_names_index_set(names=names, index_set=index_set, ngens=ngens) from sage.matrix.special import identity_matrix A = identity_matrix(R, ngens / 2) from sage.matrix.special import block_matrix gram_matrix = block_matrix([[R.zero(), A], [A, R.zero()]]) ghostsdict = {(i, j): { 0: { ('K', 0): gram_matrix[index_set.rank(i), index_set.rank(j)] } } for i in index_set for j in index_set} weights = (1, ) * (ngens // 2) + (0, ) * (ngens // 2) parity = (1, ) * ngens super(FermionicGhostsLieConformalAlgebra, self).__init__(R, ghostsdict, names=names, latex_names=latex_names, index_set=index_set, weights=weights, parity=parity, central_elements=('K', ))
def decode_supercode(Ts, c, g, k, d, Fqm, q=None, R=None): """ Tk_pub = trace of the public key over Fqm. It is a vector of length n and coordinates in Fqm. c is the ciphertext g is the support of the gabidulin, k it's dimension d is the public rank of the small error in the ciphertext R is a ring of linear polynomial, because Sage crashes due to https://trac.sagemath.org/ticket/28617. """ n = len(g) if not q: q = Fqm.characteristic() if R: s = R.twisting_morphism() else: s = Fqm.frobenius_endomorphism() R = Fqm["y", s] # skew polynomials Tinterp = [] for Tk_pub in Ts: pointsT = list(zip(g, Tk_pub)) T = reduction(R.lagrange_polynomial(pointsT)) Tinterp.append(T) G = matrix(Fqm, n, k + d, lambda i, j: (s**(j))(g[i])) S = [G] for T in Tinterp: Tm = matrix(Fqm, n, d + 1, lambda i, j: (T(g[i]))**(q**j)) S.append(Tm) Cm = matrix(Fqm, n, d + 1, lambda i, j: (s**j)(c[i])) S.append(Cm) S = block_matrix(Fqm, 1, 2 + len(Ts), S) S = S.right_kernel() S = S.basis_matrix().row(0) N = R(S.list_from_positions(range(len(S) - (d + 1)))) V = R(S.list_from_positions(range(len(S) - (d + 1), len(S)))) f, rem = (-N).left_quo_rem(V) if rem == 0: return (f, N, V, S) else: print(S) raise
def dualizing_complex(poset, base_ring=ZZ, rank=1): dim = poset.height() - 1 bound_below = -1 * dim data = [bound_below] end_base = sorted( filter(lambda c: len(c) == dim + 1, poset.maximal_chains())) for p in range(-1 * dim, 0): start_base = end_base end_base = sorted(filter(lambda c: len(c) == -1 * p, poset.chains())) #print("making differential from degree {}\n start: {}\n end:{}".format(p, start_base, end_base)) differential = dict() for x in poset.list(): point_start_base = filter(lambda c: poset.is_lequal(x, c[-1]), start_base) point_end_base = filter(lambda c: poset.is_lequal(x, c[-1]), end_base) #print("------for point {}: \n---------start:{}\n---------end:{}".format(x, point_start_base, point_end_base)) rows = [] for end_chain in point_end_base: blocks = [] for start_chain in point_start_base: if all(p in start_chain for p in end_chain): for y in start_chain: if y not in end_chain and y != start_chain[-1]: sign = 1 if start_chain.index( y) % 2 == 0 else -1 blocks.append(sign * identity_matrix(base_ring, rank)) break else: blocks.append(matrix(base_ring, rank, rank)) else: blocks.append(matrix(base_ring, rank, rank)) rows.append(blocks) differential[x] = block_matrix(rows, subdivide=False) data.append(_dualizing_sheaf(poset, p, base_ring, rank)) data.append(differential) data.append(_dualizing_sheaf(poset, 0, base_ring, rank)) if rank == 1: name = "dualizing complex of ({}, {})".format(poset, base_ring) else: name = "dualizing complex of ({}, rank-{} free module over {})".format( poset, rank, base_ring) return LocFreeSheafComplex(data, name=name)
def _multiplicity(self, X): T = block_matrix(ZZ, [[self._A[:, [self._groundset_to_index[e] for e in X]], self._Q]]) return reduce(operator.mul, [d for d in T.elementary_divisors() if d != 0], 1)
def _rank(self, X): T = block_matrix(ZZ, [[self._A[:, [self._groundset_to_index[e] for e in X]], self._Q]]) return T.rank() - self._Q.ncols()
def __init__(self, R, ngens=None, gram_matrix=None, names=None, index_set=None): """ Initialize self. TESTS:: sage: V = lie_conformal_algebras.Weyl(QQ) sage: TestSuite(V).run() """ from sage.matrix.matrix_space import MatrixSpace if ngens: try: from sage.rings.integer_ring import ZZ assert ngens in ZZ and ngens % 2 == 0 except AssertionError: raise ValueError("ngens needs to be an even positive " + "Integer, got {}".format(ngens)) if (gram_matrix is not None): if ngens is None: ngens = gram_matrix.dimensions()[0] try: assert (gram_matrix in MatrixSpace(R, ngens, ngens)) except AssertionError: raise ValueError( "The gram_matrix should be a skew-symmetric " + "{0} x {0} matrix, got {1}".format(ngens, gram_matrix)) if (not gram_matrix.is_skew_symmetric()) or \ (gram_matrix.is_singular()): raise ValueError("The gram_matrix should be a non degenerate " + "skew-symmetric {0} x {0} matrix, got {1}"\ .format(ngens,gram_matrix)) elif (gram_matrix is None): if ngens is None: ngens = 2 A = identity_matrix(R, ngens // 2) from sage.matrix.special import block_matrix gram_matrix = block_matrix([[R.zero(), A], [-A, R.zero()]]) latex_names = None if (names is None) and (index_set is None): names = 'alpha' latex_names = tuple(r'\alpha_{%d}' % i \ for i in range (ngens)) + ('K',) names, index_set = standardize_names_index_set(names=names, index_set=index_set, ngens=ngens) weyldict = {(i, j): { 0: { ('K', 0): gram_matrix[index_set.rank(i), index_set.rank(j)] } } for i in index_set for j in index_set} super(WeylLieConformalAlgebra, self).__init__(R, weyldict, names=names, latex_names=latex_names, index_set=index_set, central_elements=('K', )) self._gram_matrix = gram_matrix
def _bounded_polynomial_solutions(M, degbound, N=None, systype=None): (M, _, F, R, K, var) = __parent_info(M) if N == None: N = VectorSpace(F, M.ncols()).zero() if isinstance(N, Matrix): if N.ncols() > 1: raise ValueError("N has to be a vector") N = VectorSpace(F, M.ncols())(N.columns()[0]) if systype == None: systype = systype_fallback() op = operator(M, systype=systype) # Case: Degree bound is zero: if degbound <= 0: return ([], None) # Set up the equations and clear denominators eqs = block_matrix(1, degbound, [op(var**i) for i in range(degbound - 1, -1, -1)]) den = N.denominator().lcm(eqs.denominator()) N = den * N eqs = block_matrix(1, 2, [den * eqs, matrix(-N).transpose()]) eqs = eqs.parent().change_ring(R)(eqs) sol = [] special = None size = M.ncols() EQSdeg = max(sum([[R(i).degree() for i in j] for j in eqs], [])) + 1 eqs2 = [[0 for j in range(eqs.ncols())] for i in range(eqs.nrows() * EQSdeg)] for i in range(eqs.nrows() * EQSdeg): (row, coeff) = NN(i).quo_rem(EQSdeg) for j in range(eqs.ncols()): eqs2[i][j] = eqs[row][j][coeff] sol = matrix(eqs2).right_kernel().basis() polysol = [] # Compute the solutions as vectors with entries in Q, compress them to # vectors with polynomial entries for i in sol: v = i[:-1] l = [0 for j in range(M.ncols())] for j in range(M.ncols()): for h in range(degbound): l[j] = l[j] + var**(degbound - h - 1) * v[h * M.ncols() + j] # If the last entry is non-zero, and not all other entries are zero, it # is a solution to the inhomogeneous system if reduce((lambda x, y: y == 0 and x), v, True): continue if i[-1] != 0: if special != None: polysol.append(special - vector(l) / i[-1]) else: special = vector(l) / i[-1] else: polysol.append(vector(l)) return (polysol, special)