def affine_algebraic_patch(self, cone=None, names=None): r""" Return the affine patch corresponding to ``cone`` as an affine algebraic scheme. INPUT: - ``cone`` -- a :class:`Cone <sage.geometry.cone.ConvexRationalPolyhedralCone>` `\sigma` of the fan. It can be omitted for an affine toric variety, in which case the single generating cone is used. OUTPUT: An :class:`affine algebraic subscheme <sage.schemes.affine.affine_subscheme.AlgebraicScheme_subscheme_affine>` corresponding to the patch `\mathop{Spec}(\sigma^\vee \cap M)` associated to the cone `\sigma`. See also :meth:`affine_patch`, which expresses the patches as subvarieties of affine toric varieties instead. REFERENCES: .. David A. Cox, "The Homogeneous Coordinate Ring of a Toric Variety", Lemma 2.2. :arxiv:`alg-geom/9210008v2` EXAMPLES:: sage: P2.<x,y,z> = toric_varieties.P2() sage: cone = P2.fan().generating_cone(0) sage: V = P2.subscheme(x^3+y^3+z^3) sage: V.affine_algebraic_patch(cone) Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: z0^3 + z1^3 + 1 sage: cone = Cone([(0,1),(2,1)]) sage: A2Z2.<x,y> = AffineToricVariety(cone) sage: A2Z2.affine_algebraic_patch() Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: -z0*z1 + z2^2 sage: V = A2Z2.subscheme(x^2+y^2-1) sage: patch = V.affine_algebraic_patch(); patch Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: -z0*z1 + z2^2, z0 + z1 - 1 sage: nbhd_patch = V.neighborhood([1,0]).affine_algebraic_patch(); nbhd_patch Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: -z0*z1 + z2^2, z0 + z1 - 1 sage: nbhd_patch.embedding_center() (0, 1, 0) Here we got two defining equations. The first one describes the singularity of the ambient space and the second is the pull-back of `x^2+y^2-1` :: sage: lp = LatticePolytope([(1,0,0),(1,1,0),(1,1,1),(1,0,1),(-2,-1,-1)], ....: lattice=ToricLattice(3)) sage: X.<x,y,u,v,t> = CPRFanoToricVariety(Delta_polar=lp) sage: Y = X.subscheme(x*v+y*u+t) sage: cone = Cone([(1,0,0),(1,1,0),(1,1,1),(1,0,1)]) sage: Y.affine_algebraic_patch(cone) Closed subscheme of Affine Space of dimension 4 over Rational Field defined by: z0*z2 - z1*z3, z1 + z3 + 1 """ from sage.modules.free_module_element import vector from sage.misc.misc_c import prod ambient = self.ambient_space() fan = ambient.fan() if cone is None: assert ambient.is_affine() cone = fan.generating_cone(0) else: cone = fan.embed(cone) # R/I = C[sigma^dual cap M] R, I, dualcone = ambient._semigroup_ring(cone, names) # inhomogenize the Cox homogeneous polynomial with respect to the given cone inhomogenize = dict((ambient.coordinate_ring().gen(i), 1) for i in range(0, fan.nrays()) if i not in cone.ambient_ray_indices()) polynomials = [ p.subs(inhomogenize) for p in self.defining_polynomials() ] # map the monomial x^{D_m} to m, see reference. n_rho_matrix = cone.rays().matrix() def pullback_polynomial(p): result = R.zero() for coefficient, monomial in p: exponent = monomial.exponents()[0] exponent = [exponent[i] for i in cone.ambient_ray_indices()] exponent = vector(ZZ, exponent) m = n_rho_matrix.solve_right(exponent) assert all(x in ZZ for x in m), \ 'The polynomial '+str(p)+' does not define a ZZ-divisor!' m_coeffs = dualcone.Hilbert_coefficients(m) result += coefficient * prod( R.gen(i)**m_coeffs[i] for i in range(0, R.ngens())) return result # construct the affine algebraic scheme to use as patch polynomials = [pullback_polynomial(_) for _ in polynomials] from sage.schemes.affine.affine_space import AffineSpace patch_cover = AffineSpace(R) polynomials = list(I.gens()) + polynomials polynomials = [x for x in polynomials if not x.is_zero()] patch = patch_cover.subscheme(polynomials) # TODO: If the cone is not smooth, then the coordinate_ring() # of the affine toric variety is wrong; it should be the # G-invariant part. So we can't construct the embedding # morphism in that case. if cone.is_smooth(): x = ambient.coordinate_ring().gens() phi = [] for i in range(0, fan.nrays()): if i in cone.ambient_ray_indices(): phi.append(pullback_polynomial(x[i])) else: phi.append(1) patch._embedding_morphism = patch.hom(phi, self) else: patch._embedding_morphism = ( NotImplementedError, 'I only know how to construct embedding morphisms for smooth patches' ) try: point = self.embedding_center() except AttributeError: return patch # it remains to find the preimage of point # map m to the monomial x^{D_m}, see reference. F = ambient.coordinate_ring().fraction_field() image = [] for m in dualcone.Hilbert_basis(): x_Dm = prod([F.gen(i)**(m * n) for i, n in enumerate(fan.rays())]) image.append(x_Dm) patch._embedding_center = tuple(f(list(point)) for f in image) return patch
def affine_patch(self, I, return_embedding=False): r""" Return the `I^{th}` affine patch of this projective scheme where 'I' is a multi-index. INPUT: - ``I`` -- a list or tuple of positive integers - ``return_embedding`` -- Boolean, if true the projective embedding is also returned OUTPUT: - An affine algebraic scheme - An embedding into a product of projective space (optional) EXAMPLES:: sage: PP.<x,y,z,w,u,v> = ProductProjectiveSpaces([3,1],QQ) sage: W = PP.subscheme([y^2*z-x^3,z^2-w^2,u^3-v^3]) sage: W.affine_patch([0,1],True) (Closed subscheme of Affine Space of dimension 4 over Rational Field defined by: x0^2*x1 - 1, x1^2 - x2^2, x3^3 - 1, Scheme morphism: From: Closed subscheme of Affine Space of dimension 4 over Rational Field defined by: x0^2*x1 - 1, x1^2 - x2^2, x3^3 - 1 To: Closed subscheme of Product of projective spaces P^3 x P^1 over Rational Field defined by: -x^3 + y^2*z, z^2 - w^2, u^3 - v^3 Defn: Defined on coordinates by sending (x0, x1, x2, x3) to (1 : x0 : x1 : x2 , x3 : 1)) """ if not isinstance(I, (list, tuple)): raise TypeError( 'The argument I=%s must be a list or tuple of positive integers' % I) PP = self.ambient_space() N = PP.dimension_relative_components() if len(I) != len(N): raise ValueError('The argument I=%s must have %s entries' % (I, len(N))) I = tuple([int(i) for i in I]) # implicit type checking for i in range(len(I)): if I[i] < 0 or I[i] > N[i]: raise ValueError( "Argument i (= %s) must be between 0 and %s." % (I[i], N[i])) #see if we've already created this affine patch try: if return_embedding: return self.__affine_patches[I] else: return self.__affine_patches[I][0] except AttributeError: self.__affine_patches = {} except KeyError: pass AA = AffineSpace(PP.base_ring(), sum(N), 'x') v = list(AA.gens()) # create the projective embedding index = 0 for i in range(len(I)): v.insert(index + I[i], 1) index += N[i] + 1 phi = AA.hom(v, self) #find the image of the subscheme polys = self.defining_polynomials() xi = phi.defining_polynomials() U = AA.subscheme([f(xi) for f in polys]) phi = U.hom(v, self) self.__affine_patches.update({I: (U, phi)}) if return_embedding: return U, phi else: return U
def affine_algebraic_patch(self, cone=None, names=None): r""" Return the affine patch corresponding to ``cone`` as an affine algebraic scheme. INPUT: - ``cone`` -- a :class:`Cone <sage.geometry.cone.ConvexRationalPolyhedralCone>` `\sigma` of the fan. It can be omitted for an affine toric variety, in which case the single generating cone is used. OUTPUT: An :class:`affine algebraic subscheme <sage.schemes.affine.affine_subscheme.AlgebraicScheme_subscheme_affine>` corresponding to the patch `\mathop{Spec}(\sigma^\vee \cap M)` associated to the cone `\sigma`. See also :meth:`affine_patch`, which expresses the patches as subvarieties of affine toric varieties instead. REFERENCES: .. David A. Cox, "The Homogeneous Coordinate Ring of a Toric Variety", Lemma 2.2. :arxiv:`alg-geom/9210008v2` EXAMPLES:: sage: P2.<x,y,z> = toric_varieties.P2() sage: cone = P2.fan().generating_cone(0) sage: V = P2.subscheme(x^3+y^3+z^3) sage: V.affine_algebraic_patch(cone) Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: z0^3 + z1^3 + 1 sage: cone = Cone([(0,1),(2,1)]) sage: A2Z2.<x,y> = AffineToricVariety(cone) sage: A2Z2.affine_algebraic_patch() Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: -z0*z1 + z2^2 sage: V = A2Z2.subscheme(x^2+y^2-1) sage: patch = V.affine_algebraic_patch(); patch Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: -z0*z1 + z2^2, z0 + z1 - 1 sage: nbhd_patch = V.neighborhood([1,0]).affine_algebraic_patch(); nbhd_patch Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: -z0*z1 + z2^2, z0 + z1 - 1 sage: nbhd_patch.embedding_center() (0, 1, 0) Here we got two defining equations. The first one describes the singularity of the ambient space and the second is the pull-back of `x^2+y^2-1` :: sage: lp = LatticePolytope([(1,0,0),(1,1,0),(1,1,1),(1,0,1),(-2,-1,-1)], ....: lattice=ToricLattice(3)) sage: X.<x,y,u,v,t> = CPRFanoToricVariety(Delta_polar=lp) sage: Y = X.subscheme(x*v+y*u+t) sage: cone = Cone([(1,0,0),(1,1,0),(1,1,1),(1,0,1)]) sage: Y.affine_algebraic_patch(cone) Closed subscheme of Affine Space of dimension 4 over Rational Field defined by: z0*z2 - z1*z3, z1 + z3 + 1 """ from sage.modules.all import vector from sage.misc.all import prod ambient = self.ambient_space() fan = ambient.fan() if cone is None: assert ambient.is_affine() cone = fan.generating_cone(0) else: cone = fan.embed(cone) # R/I = C[sigma^dual cap M] R, I, dualcone = ambient._semigroup_ring(cone, names) # inhomogenize the Cox homogeneous polynomial with respect to the given cone inhomogenize = dict( (ambient.coordinate_ring().gen(i), 1) for i in range(0,fan.nrays()) if not i in cone.ambient_ray_indices() ) polynomials = [ p.subs(inhomogenize) for p in self.defining_polynomials() ] # map the monomial x^{D_m} to m, see reference. n_rho_matrix = cone.rays().matrix() def pullback_polynomial(p): result = R.zero() for coefficient, monomial in p: exponent = monomial.exponents()[0] exponent = [ exponent[i] for i in cone.ambient_ray_indices() ] exponent = vector(ZZ,exponent) m = n_rho_matrix.solve_right(exponent) assert all(x in ZZ for x in m), \ 'The polynomial '+str(p)+' does not define a ZZ-divisor!' m_coeffs = dualcone.Hilbert_coefficients(m) result += coefficient * prod(R.gen(i)**m_coeffs[i] for i in range(0,R.ngens())) return result # construct the affine algebraic scheme to use as patch polynomials = [pullback_polynomial(_) for _ in polynomials] from sage.schemes.affine.affine_space import AffineSpace patch_cover = AffineSpace(R) polynomials = list(I.gens()) + polynomials polynomials = [x for x in polynomials if not x.is_zero()] patch = patch_cover.subscheme(polynomials) # TODO: If the cone is not smooth, then the coordinate_ring() # of the affine toric variety is wrong; it should be the # G-invariant part. So we can't construct the embedding # morphism in that case. if cone.is_smooth(): x = ambient.coordinate_ring().gens() phi = [] for i in range(0,fan.nrays()): if i in cone.ambient_ray_indices(): phi.append(pullback_polynomial(x[i])) else: phi.append(1) patch._embedding_morphism = patch.hom(phi, self) else: patch._embedding_morphism = (NotImplementedError, 'I only know how to construct embedding morphisms for smooth patches') try: point = self.embedding_center() except AttributeError: return patch # it remains to find the preimage of point # map m to the monomial x^{D_m}, see reference. F = ambient.coordinate_ring().fraction_field() image = [] for m in dualcone.Hilbert_basis(): x_Dm = prod([ F.gen(i)**(m*n) for i,n in enumerate(fan.rays()) ]) image.append(x_Dm) patch._embedding_center = tuple( f(list(point)) for f in image ) return patch