def cohomology(self, d): r""" Return the ``d``-th cohomology group. EXAMPLES:: sage: E.<x,y> = ExteriorAlgebra(QQ) sage: H = E.hochschild_complex(E) sage: H.cohomology(0) Vector space of dimension 3 over Rational Field sage: H.cohomology(1) Vector space of dimension 4 over Rational Field sage: H.cohomology(2) Vector space of dimension 6 over Rational Field sage: SGA = SymmetricGroupAlgebra(QQ, 3) sage: T = SGA.trivial_representation() sage: H = SGA.hochschild_complex(T) sage: H.cohomology(0) Vector space of dimension 1 over Rational Field sage: H.cohomology(1) Vector space of dimension 0 over Rational Field sage: H.cohomology(2) Vector space of dimension 0 over Rational Field When working over general rings (except `\ZZ`) and we can construct a unitriangular basis for the image quotient, we fallback to a slower implementation using (combinatorial) free modules:: sage: R.<x,y> = QQ[] sage: SGA = SymmetricGroupAlgebra(R, 2) sage: T = SGA.trivial_representation() sage: H = SGA.hochschild_complex(T) sage: H.cohomology(1) Free module generated by {} over Multivariate Polynomial Ring in x, y over Rational Field """ if self._A.category() is not self._A.category().FiniteDimensional(): raise NotImplementedError("the algebra must be finite dimensional") maps = { d + 1: self.coboundary(d + 1).matrix(), d: self.coboundary(d).matrix() } C = ChainComplex(maps, degree_of_differential=1) try: return C.homology(d + 1) except NotImplementedError: pass # Fallback if we are not working over a field or \ZZ cb = self.coboundary(d) cb1 = self.coboundary(d + 1) ker = cb1.kernel() im_retract = ker.submodule([ker.retract(b) for b in cb.image_basis()], unitriangular=True) return ker.quotient_module(im_retract)
def cohomology(self, d): """ Return the ``d``-th cohomology group. EXAMPLES:: sage: E.<x,y> = ExteriorAlgebra(QQ) sage: H = E.hochschild_complex(E) sage: H.cohomology(0) Vector space of dimension 3 over Rational Field sage: H.cohomology(1) Vector space of dimension 4 over Rational Field sage: H.cohomology(2) Vector space of dimension 6 over Rational Field sage: SGA = SymmetricGroupAlgebra(QQ, 3) sage: T = SGA.trivial_representation() sage: H = SGA.hochschild_complex(T) sage: H.cohomology(0) Vector space of dimension 1 over Rational Field sage: H.cohomology(1) Vector space of dimension 0 over Rational Field sage: H.cohomology(2) Vector space of dimension 0 over Rational Field When working over general rings (except `\ZZ`) and we can construct a unitriangular basis for the image quotient, we fallback to a slower implementation using (combinatorial) free modules:: sage: R.<x,y> = QQ[] sage: SGA = SymmetricGroupAlgebra(R, 2) sage: T = SGA.trivial_representation() sage: H = SGA.hochschild_complex(T) sage: H.cohomology(1) Free module generated by {} over Multivariate Polynomial Ring in x, y over Rational Field """ if self._A.category() is not self._A.category().FiniteDimensional(): raise NotImplementedError("the algebra must be finite dimensional") maps = {d+1: self.coboundary(d+1).matrix(), d: self.coboundary(d).matrix()} C = ChainComplex(maps, degree_of_differential=1) try: return C.homology(d+1) except NotImplementedError: pass # Fallback if we are not working over a field or \ZZ cb = self.coboundary(d) cb1 = self.coboundary(d+1) ker = cb1.kernel() im_retract = ker.submodule([ker.retract(b) for b in cb.image_basis()], unitriangular=True) return ker.quotient_module(im_retract)
def random_chain_complex(level=1): """ Return a random chain complex, defined by specifying a single random matrix in a random degree, with differential of degree either 1 or -1. The matrix is randomly sparse or dense. :param level: measure of complexity: the larger this is, the larger the matrix can be, and the larger its degree can be in the chain complex. :type level: positive integer; optional, default 1 EXAMPLES:: sage: from sage.homology.tests import random_chain_complex sage: C = random_chain_complex() sage: C Chain complex with at most 2 nonzero terms over Integer Ring sage: C.degree_of_differential() # random: either 1 or -1 1 """ bound = 50*level nrows = randint(0, bound) ncols = randint(0, bound) sparseness = bool(randint(0, 1)) mat = random_matrix(ZZ, nrows, ncols, sparse=sparseness) dim = randint(-bound, bound) deg = 2 * randint(0, 1) - 1 # -1 or 1 return ChainComplex({dim: mat}, degree = deg)
def SChainComplex(kchaincomplex, start=0, end=15): r""" Convert the KenzoChainComplex ``kchcm`` (between dimensions ``start`` and ``end``) to a ChainComplex. INPUT: - ``kchaincomplex``- A KenzoChainComplex - ``start``- An integer number (optional, default 0) - ``end``- An integer number greater than or equal to ``start`` (optional, default 15) OUTPUT: - A ChainComplex EXAMPLES:: sage: from sage.interfaces.kenzo import KChainComplex, SChainComplex # optional - kenzo sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6]) sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6]) sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1]) sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1) # optional - kenzo sage: SChainComplex(KChainComplex(sage_chcm)) == sage_chcm # optional - kenzo True """ matrices = {} for i in range(start, end): dffr_i = chcm_mat2(kchaincomplex._kenzo, i) if ((nlig(dffr_i).python() != 0) and (ncol(dffr_i).python() != 0)): matrices[i] = k2s_matrix(convertmatrice(dffr_i)) return ChainComplex(matrices, degree=-1)
def godement_cochain_complex(self): """ Construct the Godement cochain complex of ``self``. """ # The case that the domain_space has dimension 0 if self._domain_poset.height() == 1: rank = sum(self._stalk_dict[key] for key in self._stalk_dict) differential = matrix(self._base_ring, 0, rank) return ChainComplex([rank, differential], base_ring=self._base_ring) # Other cases end_base = sorted([[x] for x in self._domain_poset.list()]) diff_dict = dict() for p in range(1, self._domain_poset.height()): start_base = end_base end_base = list(filter(lambda c: len(c)==p+1, self._domain_poset.chains())) end_base = sorted(end_base) diff_dict[p-1] = self._godement_complex_differential(start_base, end_base) return ChainComplex(diff_dict, base_ring = self._base_ring)
def cohomology_complex(self, m): r""" Return the "cohomology complex" `C^*(m)` See [Klyachko]_, equation 4.2. INPUT: - ``m`` -- tuple of integers or `M`-lattice point. A point in the dual lattice of the fan. Must be immutable. OUTPUT: The "cohomology complex" as a chain complex over the :meth:`base_ring`. EXAMPLES:: sage: P3 = toric_varieties.P(3) sage: rays = [(1,0,0), (0,1,0), (0,0,1)] sage: F1 = FilteredVectorSpace(rays, {0:[0], 1:[2], 2:[1]}) sage: F2 = FilteredVectorSpace(rays, {0:[1,2], 1:[0]}) sage: r = P3.fan().rays() sage: V = P3.sheaves.Klyachko({r[0]:F1, r[1]:F2, r[2]:F2, r[3]:F2}) sage: tau = Cone([(1,0,0), (0,1,0)]) sage: sigma = Cone([(1, 0, 0)]) sage: M = P3.fan().dual_lattice() sage: m = M(1, 1, 0); m.set_immutable() sage: V.cohomology_complex(m) Chain complex with at most 2 nonzero terms over Rational Field sage: F = CyclotomicField(3) sage: P3 = toric_varieties.P(3).change_ring(F) sage: V = P3.sheaves.Klyachko({r[0]:F1, r[1]:F2, r[2]:F2, r[3]:F2}) sage: V.cohomology_complex(m) Chain complex with at most 2 nonzero terms over Cyclotomic Field of order 3 and degree 2 """ fan = self._variety.fan() C = fan.complex() CV = [] F = self.base_ring() for dim in range(1, fan.dim() + 1): codim = fan.dim() - dim d_C = C.differential(codim) d_V = [] for j in range(d_C.ncols()): tau = fan(dim)[j] d_V_row = [] for i in range(d_C.nrows()): sigma = fan(dim - 1)[i] if sigma.is_face_of(tau): pr = self.E_quotient_projection(sigma, tau, m) d = d_C[i, j] * pr.matrix().transpose() else: E_sigma = self.E_quotient(sigma, m) E_tau = self.E_quotient(tau, m) d = zero_matrix(F, E_tau.dimension(), E_sigma.dimension()) d_V_row.append(d) d_V.append(d_V_row) d_V = block_matrix(d_V, ring=F) CV.append(d_V) from sage.homology.chain_complex import ChainComplex return ChainComplex(CV, base_ring=self.base_ring())