def cardinality(self): """ Returns the number of standard skew tableaux with shape of the skew partition skp. This uses a formula due to Aitken (see Cor. 7.16.3 of [Sta1999]_). EXAMPLES:: sage: StandardSkewTableaux([[3, 2, 1], [1, 1]]).cardinality() 8 """ outer, inner = self.skp m = len(outer) n = sum(outer) - sum(inner) outer = list(outer) inner = list(inner) + [0]*(m-len(inner)) a = zero_matrix(QQ, m) for i in range(m): for j in range(m): v = outer[i] - inner[j] - i + j if v < 0: a[i,j] = 0 else: a[i,j] = 1/factorial(v) return ZZ(factorial(n) * a.det())
def cardinality(self): """ Returns the number of standard skew tableaux with shape of the skew partition skp. This uses a formula due to Aitken (see Cor. 7.16.3 of [Sta1999]_). EXAMPLES:: sage: StandardSkewTableaux([[3, 2, 1], [1, 1]]).cardinality() 8 """ outer, inner = self.skp m = len(outer) n = sum(outer) - sum(inner) outer = list(outer) inner = list(inner) + [0] * (m - len(inner)) a = zero_matrix(QQ, m) for i in range(m): for j in range(m): v = outer[i] - inner[j] - i + j if v < 0: a[i, j] = 0 else: a[i, j] = 1 / factorial(v) return ZZ(factorial(n) * a.det())
def associated_chain_complex_morphism(self, base_ring=ZZ, augmented=False, cochain=False): """ Returns the associated chain complex morphism of self. EXAMPLES:: sage: S = simplicial_complexes.Sphere(1) sage: T = simplicial_complexes.Sphere(2) sage: H = Hom(S,T) sage: f = {0:0,1:1,2:2} sage: x = H(f) sage: x Simplicial complex morphism {0: 0, 1: 1, 2: 2} from Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} sage: a = x.associated_chain_complex_morphism() sage: a Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 3 nonzero terms over Integer Ring sage: a._matrix_dictionary {0: [0 0 0] [0 1 0] [0 0 1] [1 0 0], 1: [0 0 0] [0 1 0] [0 0 0] [1 0 0] [0 0 0] [0 0 1], 2: []} sage: x.associated_chain_complex_morphism(augmented=True) Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring to Chain complex with at most 4 nonzero terms over Integer Ring sage: x.associated_chain_complex_morphism(cochain=True) Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring sage: x.associated_chain_complex_morphism(augmented=True,cochain=True) Chain complex morphism from Chain complex with at most 4 nonzero terms over Integer Ring to Chain complex with at most 3 nonzero terms over Integer Ring sage: x.associated_chain_complex_morphism(base_ring=GF(11)) Chain complex morphism from Chain complex with at most 2 nonzero terms over Finite Field of size 11 to Chain complex with at most 3 nonzero terms over Finite Field of size 11 Some simplicial maps which reverse the orientation of a few simplices:: sage: g = {0:1, 1:2, 2:0} sage: H(g).associated_chain_complex_morphism()._matrix_dictionary {0: [0 0 0] [1 0 0] [0 1 0] [0 0 1], 1: [ 0 0 0] [-1 0 0] [ 0 0 0] [ 0 0 1] [ 0 0 0] [ 0 -1 0], 2: []} sage: X = SimplicialComplex(1, [[0, 1]]) sage: Hom(X,X)({0:1, 1:0}).associated_chain_complex_morphism()._matrix_dictionary {0: [0 1] [1 0], 1: [-1]} """ max_dim = max(self._domain.dimension(), self._codomain.dimension()) min_dim = min(self._domain.dimension(), self._codomain.dimension()) matrices = {} if augmented is True: m = matrix.Matrix(base_ring, 1, 1, 1) if not cochain: matrices[-1] = m else: matrices[-1] = m.transpose() for dim in range(min_dim + 1): # X_faces = list(self._domain.faces()[dim]) # Y_faces = list(self._codomain.faces()[dim]) X_faces = list(self._domain.n_cells(dim)) Y_faces = list(self._codomain.n_cells(dim)) num_faces_X = len(X_faces) num_faces_Y = len(Y_faces) mval = [0 for i in range(num_faces_X * num_faces_Y)] for i in X_faces: y, oriented = self(i, orientation=True) if y.dimension() < dim: pass else: mval[X_faces.index(i) + (Y_faces.index(y) * num_faces_X)] = oriented m = matrix.Matrix(base_ring, num_faces_Y, num_faces_X, mval, sparse=True) if not cochain: matrices[dim] = m else: matrices[dim] = m.transpose() for dim in range(min_dim + 1, max_dim + 1): try: l1 = len(self._codomain.n_cells(dim)) except KeyError: l1 = 0 try: l2 = len(self._domain.n_cells(dim)) except KeyError: l2 = 0 m = matrix.zero_matrix(base_ring, l1, l2, sparse=True) if not cochain: matrices[dim] = m else: matrices[dim] = m.transpose() if not cochain: return ChainComplexMorphism(matrices,\ self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\ self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain)) else: return ChainComplexMorphism(matrices,\ self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\ self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain))
def associated_chain_complex_morphism(self,base_ring=ZZ,augmented=False,cochain=False): """ Returns the associated chain complex morphism of ``self``. EXAMPLES:: sage: S = simplicial_complexes.Sphere(1) sage: T = simplicial_complexes.Sphere(2) sage: H = Hom(S,T) sage: f = {0:0,1:1,2:2} sage: x = H(f) sage: x Simplicial complex morphism {0: 0, 1: 1, 2: 2} from Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} sage: a = x.associated_chain_complex_morphism() sage: a Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 3 nonzero terms over Integer Ring sage: a._matrix_dictionary {0: [0 0 0] [0 1 0] [0 0 1] [1 0 0], 1: [0 0 0] [0 1 0] [0 0 0] [1 0 0] [0 0 0] [0 0 1], 2: []} sage: x.associated_chain_complex_morphism(augmented=True) Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring to Chain complex with at most 4 nonzero terms over Integer Ring sage: x.associated_chain_complex_morphism(cochain=True) Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring sage: x.associated_chain_complex_morphism(augmented=True,cochain=True) Chain complex morphism from Chain complex with at most 4 nonzero terms over Integer Ring to Chain complex with at most 3 nonzero terms over Integer Ring sage: x.associated_chain_complex_morphism(base_ring=GF(11)) Chain complex morphism from Chain complex with at most 2 nonzero terms over Finite Field of size 11 to Chain complex with at most 3 nonzero terms over Finite Field of size 11 Some simplicial maps which reverse the orientation of a few simplices:: sage: g = {0:1, 1:2, 2:0} sage: H(g).associated_chain_complex_morphism()._matrix_dictionary {0: [0 0 0] [1 0 0] [0 1 0] [0 0 1], 1: [ 0 0 0] [-1 0 0] [ 0 0 0] [ 0 0 1] [ 0 0 0] [ 0 -1 0], 2: []} sage: X = SimplicialComplex([[0, 1]], is_mutable=False) sage: Hom(X,X)({0:1, 1:0}).associated_chain_complex_morphism()._matrix_dictionary {0: [0 1] [1 0], 1: [-1]} """ max_dim = max(self._domain.dimension(),self._codomain.dimension()) min_dim = min(self._domain.dimension(),self._codomain.dimension()) matrices = {} if augmented is True: m = matrix.Matrix(base_ring,1,1,1) if not cochain: matrices[-1] = m else: matrices[-1] = m.transpose() for dim in range(min_dim+1): # X_faces = list(self._domain.faces()[dim]) # Y_faces = list(self._codomain.faces()[dim]) X_faces = list(self._domain.n_cells(dim)) Y_faces = list(self._codomain.n_cells(dim)) num_faces_X = len(X_faces) num_faces_Y = len(Y_faces) mval = [0 for i in range(num_faces_X*num_faces_Y)] for i in X_faces: y, oriented = self(i, orientation=True) if y.dimension() < dim: pass else: mval[X_faces.index(i)+(Y_faces.index(y)*num_faces_X)] = oriented m = matrix.Matrix(base_ring,num_faces_Y,num_faces_X,mval,sparse=True) if not cochain: matrices[dim] = m else: matrices[dim] = m.transpose() for dim in range(min_dim+1,max_dim+1): try: l1 = len(self._codomain.n_cells(dim)) except KeyError: l1 = 0 try: l2 = len(self._domain.n_cells(dim)) except KeyError: l2 = 0 m = matrix.zero_matrix(base_ring,l1,l2,sparse=True) if not cochain: matrices[dim] = m else: matrices[dim] = m.transpose() if not cochain: return ChainComplexMorphism(matrices,\ self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\ self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain)) else: return ChainComplexMorphism(matrices,\ self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\ self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain))
def __init__(self, matrices, C, D): """ Create a morphism from a dictionary of matrices. EXAMPLES:: from sage.matrix.constructor import zero_matrix sage: S = simplicial_complexes.Sphere(1) sage: S Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} sage: C = S.chain_complex() sage: C.differential() {0: [], 1: [ 1 1 0] [ 0 -1 -1] [-1 0 1]} sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)} sage: G = Hom(C,C) sage: x = G(f) sage: x Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring sage: x._matrix_dictionary {0: [0 0 0] [0 0 0] [0 0 0], 1: [0 0 0] [0 0 0] [0 0 0]} Check that the bug in :trac:`13220` has been fixed:: sage: X = simplicial_complexes.Simplex(1) sage: Y = simplicial_complexes.Simplex(0) sage: g = Hom(X,Y)({0:0, 1:0}) sage: g.associated_chain_complex_morphism() Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 1 nonzero terms over Integer Ring """ if C._grading_group != ZZ: raise NotImplementedError, "Chain complex morphisms are not implemented over gradings other than ZZ." d = C._degree if d != D._degree: raise ValueError, "Chain complex morphisms are not defined for chain complexes of different degrees." if d != -1 and d != 1: raise NotImplementedError, "Chain complex morphisms are not implemented for degrees besides -1 and 1." dim_min = min(min(C.differential().keys()), min(D.differential().keys())) dim_max = max(max(C.differential().keys()), max(D.differential().keys())) if not C.base_ring() == D.base_ring(): raise NotImplementedError, "Chain complex morphisms between chain complexes of different base rings are not implemented." for i in range(dim_min, dim_max): try: matrices[i] except KeyError: matrices[i] = matrix.zero_matrix(C.base_ring(), D.differential()[i].ncols(), C.differential()[i].ncols(), sparse=True) try: matrices[i + 1] except KeyError: matrices[i + 1] = matrix.zero_matrix( C.base_ring(), D.differential()[i + 1].ncols(), C.differential()[i + 1].ncols(), sparse=True) if d == -1: if (i + 1) in C.differential().keys() and ( i + 1) in D.differential().keys(): if not matrices[i] * C.differential( )[i + 1] == D.differential()[i + 1] * matrices[i + 1]: raise ValueError, "Matrices must define a chain complex morphism." elif (i + 1) in C.differential().keys(): if not (matrices[i] * C.differential()[i + 1]).is_zero(): raise ValueError, "Matrices must define a chain complex morphism." elif (i + 1) in D.differential().keys(): if not (D.differential()[i + 1] * matrices[i + 1]).is_zero(): raise ValueError, "Matrices must define a chain complex morphism." else: if i in C.differential().keys() and i in D.differential().keys( ): if not matrices[i + 1] * C.differential( )[i] == D.differential()[i] * matrices[i]: raise ValueError, "Matrices must define a chain complex morphism." elif i in C.differential().keys(): if not (matrices[i + 1] * C.differential()[i]).is_zero(): raise ValueError, "Matrices must define a chain complex morphism." elif i in D.differential().keys(): if not (D.differential()[i] * matrices[i]).is_zero(): raise ValueError, "Matrices must define a chain complex morphism." self._matrix_dictionary = matrices self._domain = C self._codomain = D
def __init__(self, matrices, C, D): """ Create a morphism from a dictionary of matrices. EXAMPLES:: from sage.matrix.constructor import zero_matrix sage: S = simplicial_complexes.Sphere(1) sage: S Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} sage: C = S.chain_complex() sage: C.differential() {0: [], 1: [ 1 1 0] [ 0 -1 -1] [-1 0 1]} sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)} sage: G = Hom(C,C) sage: x = G(f) sage: x Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring sage: x._matrix_dictionary {0: [0 0 0] [0 0 0] [0 0 0], 1: [0 0 0] [0 0 0] [0 0 0]} Check that the bug in :trac:`13220` has been fixed:: sage: X = simplicial_complexes.Simplex(1) sage: Y = simplicial_complexes.Simplex(0) sage: g = Hom(X,Y)({0:0, 1:0}) sage: g.associated_chain_complex_morphism() Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 1 nonzero terms over Integer Ring """ if C._grading_group != ZZ: raise NotImplementedError, "Chain complex morphisms are not implemented over gradings other than ZZ." d = C._degree if d != D._degree: raise ValueError, "Chain complex morphisms are not defined for chain complexes of different degrees." if d != -1 and d != 1: raise NotImplementedError, "Chain complex morphisms are not implemented for degrees besides -1 and 1." dim_min = min(min(C.differential().keys()), min(D.differential().keys())) dim_max = max(max(C.differential().keys()), max(D.differential().keys())) if not C.base_ring() == D.base_ring(): raise NotImplementedError, "Chain complex morphisms between chain complexes of different base rings are not implemented." for i in range(dim_min, dim_max): try: matrices[i] except KeyError: matrices[i] = matrix.zero_matrix( C.base_ring(), D.differential()[i].ncols(), C.differential()[i].ncols(), sparse=True ) try: matrices[i + 1] except KeyError: matrices[i + 1] = matrix.zero_matrix( C.base_ring(), D.differential()[i + 1].ncols(), C.differential()[i + 1].ncols(), sparse=True ) if d == -1: if (i + 1) in C.differential().keys() and (i + 1) in D.differential().keys(): if not matrices[i] * C.differential()[i + 1] == D.differential()[i + 1] * matrices[i + 1]: raise ValueError, "Matrices must define a chain complex morphism." elif (i + 1) in C.differential().keys(): if not (matrices[i] * C.differential()[i + 1]).is_zero(): raise ValueError, "Matrices must define a chain complex morphism." elif (i + 1) in D.differential().keys(): if not (D.differential()[i + 1] * matrices[i + 1]).is_zero(): raise ValueError, "Matrices must define a chain complex morphism." else: if i in C.differential().keys() and i in D.differential().keys(): if not matrices[i + 1] * C.differential()[i] == D.differential()[i] * matrices[i]: raise ValueError, "Matrices must define a chain complex morphism." elif i in C.differential().keys(): if not (matrices[i + 1] * C.differential()[i]).is_zero(): raise ValueError, "Matrices must define a chain complex morphism." elif i in D.differential().keys(): if not (D.differential()[i] * matrices[i]).is_zero(): raise ValueError, "Matrices must define a chain complex morphism." self._matrix_dictionary = matrices self._domain = C self._codomain = D
def __init__(self, matrices, C, D, check=True): """ Create a morphism from a dictionary of matrices. EXAMPLES:: from sage.matrix.constructor import zero_matrix sage: S = simplicial_complexes.Sphere(1) sage: S Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} sage: C = S.chain_complex() sage: C.differential() {0: [], 1: [ 1 1 0] [ 0 -1 -1] [-1 0 1], 2: []} sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)} sage: G = Hom(C,C) sage: x = G(f) sage: x Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring sage: x._matrix_dictionary {0: [0 0 0] [0 0 0] [0 0 0], 1: [0 0 0] [0 0 0] [0 0 0]} Check that the bug in :trac:`13220` has been fixed:: sage: X = simplicial_complexes.Simplex(1) sage: Y = simplicial_complexes.Simplex(0) sage: g = Hom(X,Y)({0:0, 1:0}) sage: g.associated_chain_complex_morphism() Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 1 nonzero terms over Integer Ring """ if not C.base_ring() == D.base_ring(): raise NotImplementedError('morphisms between chain complexes of different' ' base rings are not implemented') d = C.degree_of_differential() if d != D.degree_of_differential(): raise ValueError('degree of differential does not match') from sage.misc.misc import uniq degrees = uniq(C.differential().keys() + D.differential().keys()) initial_matrices = dict(matrices) matrices = dict() for i in degrees: if i - d not in degrees: if not (C.free_module_rank(i) == D.free_module_rank(i) == 0): raise ValueError('{} and {} are not rank 0 in degree {}'.format(C, D, i)) continue try: matrices[i] = initial_matrices.pop(i) except KeyError: matrices[i] = matrix.zero_matrix(C.base_ring(), D.differential(i).ncols(), C.differential(i).ncols(), sparse=True) if check: # all remaining matrices given must be 0x0 if not all(m.ncols() == m.nrows() == 0 for m in initial_matrices.values()): raise ValueError('the remaining matrices are not empty') # check commutativity for i in degrees: if i - d not in degrees: if not (C.free_module_rank(i) == D.free_module_rank(i) == 0): raise ValueError('{} and {} are not rank 0 in degree {}'.format(C, D, i)) continue if i + d not in degrees: if not (C.free_module_rank(i+d) == D.free_module_rank(i+d) == 0): raise ValueError('{} and {} are not rank 0 in degree {}'.format(C, D, i+d)) continue Dm = D.differential(i) * matrices[i] mC = matrices[i+d] * C.differential(i) if mC != Dm: raise ValueError('matrices must define a chain complex morphism') self._matrix_dictionary = matrices self._domain = C self._codomain = D
def cup_product_matrix(self, prec=10): """ Computes the matrix whose $ij$th entry is the cup product pairing of elements of the basis of de Rham cohomology for the hyperelliptic curve, i.e., $a_{i+1,j+1} = [w_i]\cup [w_j] = Res(w_j*\integral(w_i))$, where $w_i = x^i dx/2y, i = 0,..., 2g-1$. INPUT OUTPUT EXAMPLES: sage: R.<x> = QQ[] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: H.cup_product_matrix() [ 0 0 0 1/3] [ 0 0 1 0] [ 0 -1 0 -23/3] [ -1/3 0 23/3 0] sage: H = HyperellipticCurve(x^5 + 33*x^4/16 + 3*x^3/4 + 3*x^2/8 - x/4 + 1/16) sage: H.cup_product_matrix() [ 0 0 0 1/3] [ 0 0 1 -11/8] [ 0 -1 0 1/4] [ -1/3 11/8 -1/4 0] sage: H = HyperellipticCurve(x^3-x+1) sage: H.cup_product_matrix() [ 0 1] [-1 0] sage: H = HyperellipticCurve(x^9+3) sage: H.cup_product_matrix() [ 0 0 0 0 0 0 0 1/7] [ 0 0 0 0 0 0 1/5 0] [ 0 0 0 0 0 1/3 0 0] [ 0 0 0 0 1 0 0 0] [ 0 0 0 -1 0 0 0 0] [ 0 0 -1/3 0 0 0 0 0] [ 0 -1/5 0 0 0 0 0 0] [-1/7 0 0 0 0 0 0 0] AUTHOR: - Jennifer Balakrishnan (2007-12) """ g = self.genus() if 10 * g > prec: prec = 10 * g x, y = self.local_coordinates_at_infinity(prec) if self.hyperelliptic_polynomials()[0].degree() == 2 * g + 1: xprime = x.derivative() w = [x**i * xprime / (2 * y) for i in range(2 * g)] wint = [(w[i]).integral() for i in range(2 * g)] B = matrix(self.base_ring(), 2 * g, 2 * g, [(w[j] * wint[i]).residue() for i in range(2 * g) for j in range(2 * g)]) else: B = zero_matrix(self.base_ring(), 2 * g, 2 * g) g = self.genus() locs = [(x, y), (x, -y)] for i in range(len(locs)): xx, yy = locs[i] wg = (xx**g) * xx.derivative() / (2 * yy) assert wg.valuation() == -1 c = wg.residue() L = [] for i in range(g + 1, 2 * g + 1): diff = xx**i * xx.derivative() / (2 * yy) r = diff.residue() L = L + [r * wg - c * diff] w = [xx**i * xx.derivative() / (2 * yy) for i in range(g)] + L wint = [(w[i]).integral() for i in range(2 * g)] Bplus = matrix(self.base_ring(), 2 * g, 2 * g, [(w[j] * wint[i]).residue() for i in range(2 * g) for j in range(2 * g)]) print Bplus B = B + Bplus return B