def F(z,level = 0,method = 'moments'): R = PolynomialRing(z.parent(),'x,y').fraction_field() Rx = PolynomialRing(z.parent(),'x1').fraction_field() x1 = Rx.gen() subst = R.hom([x1,z],codomain = Rx) x,y = R.gens() center = self.parent()._source._BT.find_containing_affinoid(z) zbar = z.trace()-z f = R(1)/(x-y) k = self.parent()._n+2 V = [f] for ii in range(order): V = [v.derivative(y) for v in V]+[k/(y-zbar)*v for v in V] k += 2 return sum([self.integrate(subst(v),center,level,method) for v in V])
def F(z): R=PolynomialRing(z.parent(),'x,y').fraction_field() Rx=PolynomialRing(z.parent(),'x1').fraction_field() x1=Rx.gen() subst=R.hom([x1,z],codomain=Rx) x,y=R.gens() center=self._parent._X._BT.find_containing_affinoid(z) zbar=z.trace()-z f=R(1)/(x-y) k=self._parent._k V=[f] for ii in range(order): V=[v.derivative(y) for v in V]+[k/(y-zbar)*v for v in V] k+=2 return sum([self.riemann_sum(subst(v),center,level) for v in V])
def _forward_image(self, f, check=True): r""" Compute the forward image of this subscheme by the morphism ``f``. The forward image is computed through elimination and ``f`` must be a morphism for this to be well defined. In particular, let $X = V(h_1,\ldots, h_t)$ and define the ideal $I = (h_1,\ldots,h_t,y_0-f_0(\bar{x}), \ldots, y_n-f_n(\bar{x}))$. Then the elimination ideal $I_{n+1} = I \cap K[y_0,\ldots,y_n]$ is a homogeneous ideal and $self(X) = V(I_{n+1})$. INPUT: - ``f`` -- a map whose domain contains ``self`` - ``check`` -- Boolean, if `False` no input checking is done OUTPUT: - a subscheme in the codomain of ``f``. EXAMPLES:: sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2) sage: H = End(PS) sage: f = H([x^2, y^2-2*z^2, z^2]) sage: X = PS.subscheme(y-2*z) sage: X._forward_image(f) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: y - 2*z :: sage: set_verbose(None) sage: PS.<x,y,z,w> = ProjectiveSpace(ZZ, 3) sage: H = End(PS) sage: f = H([y^2, x^2, w^2, z^2]) sage: X = PS.subscheme([z^2+y*w, x-w]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Integer Ring defined by: y - z, x*z - w^2 :: sage: PS.<x,y,z,w> = ProjectiveSpace(CC, 3) sage: H = End(PS) sage: f = H([x^2 + y^2, y^2, z^2-y^2, w^2]) sage: X = PS.subscheme([z-2*w]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Complex Field with 53 bits of precision defined by: y + z + (-4.00000000000000)*w :: sage: R.<t> = PolynomialRing(QQ) sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2) sage: H = End(P) sage: f = H([x^2 + 2*y*z, t^2*y^2, z^2]) sage: f([t^2*y-z]) Closed subscheme of Projective Space of dimension 2 over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by: y + (-1/t^2)*z :: sage: set_verbose(-1) sage: PS.<x,y,z> = ProjectiveSpace(Qp(3), 2) sage: H = End(PS) sage: f = H([x^2,2*y^2,z^2]) sage: X = PS.subscheme([2*x-y,z]) sage: f(X) Closed subscheme of Projective Space of dimension 2 over 3-adic Field with capped relative precision 20 defined by: z, x + (1 + 3^2 + 3^4 + 3^6 + 3^8 + 3^10 + 3^12 + 3^14 + 3^16 + 3^18 + O(3^20))*y :: sage: R.<y0,y1,y2,y3> = PolynomialRing(QQ) sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2) sage: H = End(P) sage: f = H([y0*x^2+y1*z^2, y2*y^2+y3*z^2, z^2]) sage: X = P.subscheme(x*z) sage: X._forward_image(f) Closed subscheme of Projective Space of dimension 2 over Fraction Field of Multivariate Polynomial Ring in y0, y1, y2, y3 over Rational Field defined by: x*z + (-y1)*z^2 :: sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2) sage: P5.<z0,z1,z2,z3,z4,z5> = ProjectiveSpace(QQ, 5) sage: H = Hom(P2, P5) sage: f = H([x^2,x*y,x*z,y^2,y*z,z^2]) #Veronese map sage: X = P2.subscheme([]) sage: f(X) Closed subscheme of Projective Space of dimension 5 over Rational Field defined by: -z4^2 + z3*z5, -z2*z4 + z1*z5, -z2*z3 + z1*z4, -z2^2 + z0*z5, -z1*z2 + z0*z4, -z1^2 + z0*z3 :: sage: P2.<x,y,z>=ProjectiveSpace(QQ, 2) sage: P3.<u,v,w,t>=ProjectiveSpace(QQ, 3) sage: H = Hom(P2, P3) sage: X = P2.subscheme([x-y,x-z]) sage: f = H([x^2,y^2,z^2,x*y]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: w - t, v - t, u - t :: sage: P1.<u,v> = ProjectiveSpace(QQ, 1) sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2) sage: H = Hom(P2,P1) sage: f = H([x^2,y*z]) sage: X = P2.subscheme([x-y]) sage: f(X) Traceback (most recent call last): ... TypeError: map must be a morphism :: sage: PS.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: H = End(PS) sage: f = H([x^3, x*y^2, x*z^2]) sage: X = PS.subscheme([x-y]) sage: X._forward_image(f) Traceback (most recent call last): ... TypeError: map must be a morphism :: sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2) sage: P1.<u,v> = ProjectiveSpace(QQ, 1) sage: Y = P1.subscheme([u-v]) sage: H = End(PS) sage: f = H([x^2, y^2, z^2]) sage: Y._forward_image(f) Traceback (most recent call last): ... TypeError: subscheme must be in ambient space of domain of map """ dom = f.domain() codom = f.codomain() if check: if not f.is_morphism(): raise TypeError("map must be a morphism") if self.ambient_space() != dom: raise TypeError( "subscheme must be in ambient space of domain of map") CR_dom = dom.coordinate_ring() CR_codom = codom.coordinate_ring() n = CR_dom.ngens() m = CR_codom.ngens() #can't call eliminate if the base ring is polynomial so we do it ourselves #with a lex ordering R = PolynomialRing(f.base_ring(), n + m, 'tempvar', order='lex') Rvars = R.gens()[0:n] phi = CR_dom.hom(Rvars, R) zero = n * [0] psi = R.hom(zero + list(CR_codom.gens()), CR_codom) #set up ideal L = R.ideal([phi(t) for t in self.defining_polynomials()] + [R.gen(n + i) - phi(f[i]) for i in range(m)]) G = L.groebner_basis() #eliminate newL = [] #get only the elimination ideal portion for i in range(len(G) - 1, 0, -1): v = G[i].variables() if all(Rvars[j] not in v for j in range(n)): newL.append(psi(G[i])) return (codom.subscheme(newL))
def Chow_form(self): r""" Returns the Chow form associated to this subscheme. For a `k`-dimensional subvariety of `\mathbb{P}^N` of degree `D`. The `(N-k-1)`-dimensional projective linear subspaces of `\mathbb{P}^N` meeting `X` form a hypersurface in the Grassmannian `G(N-k-1,N)`. The homogeneous form of degree `D` defining this hypersurface in Plucker coordinates is called the Chow form of `X`. The base ring needs to be a number field, finite field, or `\QQbar`. ALGORITHM: For a `k`-dimension subscheme `X` consider the `k+1` linear forms `l_i = u_{i0}x_0 + \cdots + u_{in}x_n`. Let `J` be the ideal in the polynomial ring `K[x_i,u_{ij}]` defined by the equations of `X` and the `l_i`. Let `J'` be the saturation of `J` with respect to the irrelevant ideal of the ambient projective space of `X`. The elimination ideal `I = J' \cap K[u_{ij}]` is a principal ideal, let `R` be its generator. The Chow form is obtained by writing `R` as a polynomial in Plucker coordinates (i.e. bracket polynomials). [DalbecSturmfels]_. OUTPUT: a homogeneous polynomial. REFERENCES: .. [DalbecSturmfels] J. Dalbec and B. Sturmfels. Invariant methods in discrete and computational geometry, chapter Introduction to Chow forms, pages 37-58. Springer Netherlands, 1994. EXAMPLES:: sage: P.<x0,x1,x2,x3> = ProjectiveSpace(GF(17), 3) sage: X = P.subscheme([x3+x1,x2-x0,x2-x3]) sage: X.Chow_form() t0 - t1 + t2 + t3 :: sage: P.<x0,x1,x2,x3> = ProjectiveSpace(QQ,3) sage: X = P.subscheme([x3^2 -101*x1^2 - 3*x2*x0]) sage: X.Chow_form() t0^2 - 101*t2^2 - 3*t1*t3 :: sage: P.<x0,x1,x2,x3>=ProjectiveSpace(QQ,3) sage: X = P.subscheme([x0*x2-x1^2, x0*x3-x1*x2, x1*x3-x2^2]) sage: Ch = X.Chow_form(); Ch t2^3 + 2*t2^2*t3 + t2*t3^2 - 3*t1*t2*t4 - t1*t3*t4 + t0*t4^2 + t1^2*t5 sage: Y = P.subscheme_from_Chow_form(Ch, 1); Y Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: x2^2*x3 - x1*x3^2, -x2^3 + x0*x3^2, -x2^2*x3 + x1*x3^2, x1*x2*x3 - x0*x3^2, 3*x1*x2^2 - 3*x0*x2*x3, -2*x1^2*x3 + 2*x0*x2*x3, -3*x1^2*x2 + 3*x0*x1*x3, x1^3 - x0^2*x3, x2^3 - x1*x2*x3, -3*x1*x2^2 + 2*x1^2*x3 + x0*x2*x3, 2*x0*x2^2 - 2*x0*x1*x3, 3*x1^2*x2 - 2*x0*x2^2 - x0*x1*x3, -x0*x1*x2 + x0^2*x3, -x0*x1^2 + x0^2*x2, -x1^3 + x0*x1*x2, x0*x1^2 - x0^2*x2 sage: I = Y.defining_ideal() sage: I.saturation(I.ring().ideal(list(I.ring().gens())))[0] Ideal (x2^2 - x1*x3, x1*x2 - x0*x3, x1^2 - x0*x2) of Multivariate Polynomial Ring in x0, x1, x2, x3 over Rational Field """ I = self.defining_ideal() P = self.ambient_space() R = P.coordinate_ring() N = P.dimension() + 1 d = self.dimension() # create the ring for the generic linear hyperplanes # u0x0 + u1x1 + ... SS = PolynomialRing(R.base_ring(), 'u', N * (d + 1), order='lex') vars = SS.variable_names() + R.variable_names() S = PolynomialRing(R.base_ring(), vars, order='lex') n = S.ngens() newcoords = [S.gen(n - N + t) for t in range(N)] # map the generators of the subscheme into the ring with the hyperplane variables phi = R.hom(newcoords, S) phi(self.defining_polynomials()[0]) # create the dim(X)+1 linear hyperplanes l = [] for i in range(d + 1): t = 0 for j in range(N): t += S.gen(N * i + j) * newcoords[j] l.append(t) # intersect the hyperplanes with X J = phi(I) + S.ideal(l) # saturate the ideal with respect to the irrelevant ideal J2 = J.saturation(S.ideal([phi(u) for u in R.gens()]))[0] # eliminate the original variables to be left with the hyperplane coefficients 'u' E = J2.elimination_ideal(newcoords) # create the plucker coordinates D = binomial(N, N - d - 1) #number of plucker coordinates tvars = [str('t') + str(i) for i in range(D)] #plucker coordinates T = PolynomialRing(R.base_ring(), tvars + list(S.variable_names()), order='lex') L = [] coeffs = [ T.gen(i) for i in range(0 + len(tvars), N * (d + 1) + len(tvars)) ] M = matrix(T, d + 1, N, coeffs) i = 0 for c in M.minors(d + 1): L.append(T.gen(i) - c) i += 1 # create the ideal that we can use for eliminating to get a polynomial # in the plucker coordinates (brackets) br = T.ideal(L) # create a mapping into a polynomial ring over the plucker coordinates # and the hyperplane coefficients psi = S.hom(coeffs + [0 for _ in range(N)], T) E2 = T.ideal([psi(u) for u in E.gens()] + br) # eliminate the hyperplane coefficients CH = E2.elimination_ideal(coeffs) # CH should be a principal ideal, but because of the relations among # the plucker coordinates, the elimination will probably have several generators # get the relations among the plucker coordinates rel = br.elimination_ideal(coeffs) # reduce CH with respect to the relations reduced = [] for f in CH.gens(): reduced.append(f.reduce(rel)) # find the principal generator # polynomial ring in just the plucker coordinates T2 = PolynomialRing(R.base_ring(), tvars) alp = T.hom(tvars + (N * (d + 1) + N) * [0], T2) # get the degrees of the reduced generators of CH degs = [u.degree() for u in reduced] mind = max(degs) # need the smallest degree form that did not reduce to 0 for d in degs: if d < mind and d > 0: mind = d ind = degs.index(mind) CF = reduced[ind] #this should be the Chow form of X # check that it is correct (i.e., it is a principal generator for CH + the relations) rel2 = rel + [CF] assert all(f in rel2 for f in CH.gens()), "did not find a principal generator" return alp(CF)
def segre_embedding(self, PP=None): r""" Return the Segre embedding of this subscheme into the appropriate projective space. INPUT: - ``PP`` -- (default: ``None``) ambient image projective space; this is constructed if it is not given. OUTPUT: Hom from this subscheme to the appropriate subscheme of projective space EXAMPLES:: sage: X.<x,y,z,w,u,v> = ProductProjectiveSpaces([2,2], QQ) sage: P = ProjectiveSpace(QQ,8,'t') sage: L = (-w - v)*x + (-w*y - u*z) sage: Q = (-u*w - v^2)*x^2 + ((-w^2 - u*w + (-u*v - u^2))*y + (-w^2 - u*v)*z)*x + \ ((-w^2 - u*w - u^2)*y^2 + (-u*w - v^2)*z*y + (-w^2 + (-v - u)*w)*z^2) sage: W = X.subscheme([L,Q]) sage: phi = W.segre_embedding(P) sage: phi.codomain().ambient_space() == P True :: sage: PP.<x,y,u,v,s,t> = ProductProjectiveSpaces([1,1,1], CC) sage: PP.subscheme([]).segre_embedding() Scheme morphism: From: Closed subscheme of Product of projective spaces P^1 x P^1 x P^1 over Complex Field with 53 bits of precision defined by: (no polynomials) To: Closed subscheme of Projective Space of dimension 7 over Complex Field with 53 bits of precision defined by: -u5*u6 + u4*u7, -u3*u6 + u2*u7, -u3*u4 + u2*u5, -u3*u5 + u1*u7, -u3*u4 + u1*u6, -u3*u4 + u0*u7, -u2*u4 + u0*u6, -u1*u4 + u0*u5, -u1*u2 + u0*u3 Defn: Defined by sending (x : y , u : v , s : t) to (x*u*s : x*u*t : x*v*s : x*v*t : y*u*s : y*u*t : y*v*s : y*v*t). :: sage: PP.<x,y,z,u,v,s,t> = ProductProjectiveSpaces([2,1,1], ZZ) sage: PP.subscheme([x^3, u-v, s^2-t^2]).segre_embedding() Scheme morphism: From: Closed subscheme of Product of projective spaces P^2 x P^1 x P^1 over Integer Ring defined by: x^3, u - v, s^2 - t^2 To: Closed subscheme of Projective Space of dimension 11 over Integer Ring defined by: u10^2 - u11^2, u9 - u11, u8 - u10, -u7*u10 + u6*u11, u6*u10 - u7*u11, u6^2 - u7^2, u5 - u7, u4 - u6, u3^3, -u3*u10 + u2*u11, u2*u10 - u3*u11, -u3*u6 + u2*u7, u2*u6 - u3*u7, u2*u3^2, u2^2 - u3^2, u1 - u3, u0 - u2 Defn: Defined by sending (x : y : z , u : v , s : t) to (x*u*s : x*u*t : x*v*s : x*v*t : y*u*s : y*u*t : y*v*s : y*v*t : z*u*s : z*u*t : z*v*s : z*v*t). """ AS = self.ambient_space() CR = AS.coordinate_ring() N = AS.dimension_relative_components() M = prod([n + 1 for n in N]) - 1 vars = list(AS.coordinate_ring().variable_names()) + [ 'u' + str(i) for i in range(M + 1) ] R = PolynomialRing(AS.base_ring(), AS.ngens() + M + 1, vars, order='lex') #set-up the elimination for the segre embedding mapping = [] k = AS.ngens() index = AS.num_components() * [0] for count in range(M + 1): mapping.append( R.gen(k + count) - prod([CR(AS[i].gen(index[i])) for i in range(len(index))])) for i in range(len(index) - 1, -1, -1): if index[i] == N[i]: index[i] = 0 else: index[i] += 1 break #only increment once #change the defining ideal of the subscheme into the variables I = R.ideal(list(self.defining_polynomials()) + mapping) J = I.groebner_basis() s = set(R.gens()[:AS.ngens()]) n = len(J) - 1 L = [] while s.isdisjoint(J[n].variables()): L.append(J[n]) n = n - 1 #create new subscheme if PP is None: PS = ProjectiveSpace(self.base_ring(), M, R.gens()[AS.ngens():]) Y = PS.subscheme(L) else: if PP.dimension_relative() != M: raise ValueError( "projective space %s must be dimension %s") % (PP, M) S = PP.coordinate_ring() psi = R.hom([0] * k + list(S.gens()), S) L = [psi(l) for l in L] Y = PP.subscheme(L) #create embedding for points mapping = [] index = AS.num_components() * [0] for count in range(M + 1): mapping.append( prod([CR(AS[i].gen(index[i])) for i in range(len(index))])) for i in range(len(index) - 1, -1, -1): if index[i] == N[i]: index[i] = 0 else: index[i] += 1 break #only increment once phi = self.hom(mapping, Y) return phi
def homogenize(self,n,newvar='h'): r""" Return the homogenization of ``self``. If ``self.domain()`` is a subscheme, the domain of the homogenized map is the projective embedding of ``self.domain()`` INPUT: - ``newvar`` -- the name of the homogenization variable (only used when ``self.domain()`` is affine space) - ``n`` -- the n-th projective embedding into projective space OUTPUT: - :class:`SchemMorphism_polynomial_projective_space` EXAMPLES:: sage: A.<x,y>=AffineSpace(ZZ,2) sage: H=Hom(A,A) sage: f=H([(x^2-2)/x^5,y^2]) sage: f.homogenize(2,'z') Scheme endomorphism of Projective Space of dimension 2 over Integer Ring Defn: Defined on coordinates by sending (x : y : z) to (x^2*z^5 - 2*z^7 : x^5*y^2 : x^5*z^2) :: sage: A.<x,y>=AffineSpace(CC,2) sage: H=Hom(A,A) sage: f=H([(x^2-2)/(x*y),y^2-x]) sage: f.homogenize(0,'z') Scheme endomorphism of Projective Space of dimension 2 over Complex Field with 53 bits of precision Defn: Defined on coordinates by sending (x : y : z) to (x*y*z^2 : x^2*z^2 + (-2.00000000000000)*z^4 : x*y^3 - x^2*y*z) :: sage: A.<x,y>=AffineSpace(ZZ,2) sage: X=A.subscheme([x-y^2]) sage: H=Hom(X,X) sage: f=H([9*y^2,3*y]) sage: f.homogenize(2) Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 over Integer Ring defined by: -x1^2 + x0*x2 Defn: Defined on coordinates by sending (x0 : x1 : x2) to (9*x0*x2 : 3*x1*x2 : x2^2) :: sage: R.<t>=PolynomialRing(ZZ) sage: A.<x,y>=AffineSpace(R,2) sage: H=Hom(A,A) sage: f=H([(x^2-2)/y,y^2-x]) sage: f.homogenize(0,'z') Scheme endomorphism of Projective Space of dimension 2 over Univariate Polynomial Ring in t over Integer Ring Defn: Defined on coordinates by sending (x : y : z) to (y*z^2 : x^2*z + (-2)*z^3 : y^3 - x*y*z) """ A=self.domain() B=self.codomain() N=A.ambient_space().dimension_relative() NB=B.ambient_space().dimension_relative() Vars=list(A.ambient_space().variable_names())+[newvar] S=PolynomialRing(A.base_ring(),Vars) try: l=lcm([self[i].denominator() for i in range(N)]) except Exception: #no lcm l=prod([self[i].denominator() for i in range(N)]) from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.multi_polynomial_ring_generic import MPolynomialRing_generic if self.domain().base_ring()==RealField() or self.domain().base_ring()==ComplexField(): F=[S(((self[i]*l).numerator())._maxima_().divide(self[i].denominator())[0].sage()) for i in range(N)] elif isinstance(self.domain().base_ring(),(PolynomialRing_general,MPolynomialRing_generic)): F=[S(((self[i]*l).numerator())._maxima_().divide(self[i].denominator())[0].sage()) for i in range(N)] else: F=[S(self[i]*l) for i in range(N)] F.insert(n,S(l)) d=max([F[i].degree() for i in range(N+1)]) F=[F[i].homogenize(newvar)*S.gen(N)**(d-F[i].degree()) for i in range(N+1)] from sage.schemes.affine.affine_space import is_AffineSpace if is_AffineSpace(A)==True: from sage.schemes.projective.projective_space import ProjectiveSpace X=ProjectiveSpace(A.base_ring(),NB,Vars) else: X=A.projective_embedding(n).codomain() phi=S.hom(X.ambient_space().gens(),X.ambient_space().coordinate_ring()) F=[phi(f) for f in F] H=Hom(X,X) return(H(F))
def _forward_image(self, f, check = True): """ Compute the forward image of this subscheme by the morphism ``f``. The forward image is computed through elimination and ``f`` must be a morphism for this to be well defined. In particular, let $X = V(h_1,\ldots, h_t)$ and define the ideal $I = (h_1,\ldots,h_t,y_0-f_0(\bar{x}), \ldots, y_n-f_n(\bar{x}))$. Then the elimination ideal $I_{n+1} = I \cap K[y_0,\ldots,y_n]$ is a homogeneous ideal and $self(X) = V(I_{n+1})$. INPUT: - ``f`` -- a map whose domain contains ``self`` - ``check`` -- Boolean, if `False` no input checking is done OUTPUT: - a subscheme in the codomain of ``f``. EXAMPLES:: sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2) sage: H = End(PS) sage: f = H([x^2, y^2-2*z^2, z^2]) sage: X = PS.subscheme(y-2*z) sage: X._forward_image(f) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: y - 2*z :: sage: set_verbose(None) sage: PS.<x,y,z,w> = ProjectiveSpace(ZZ, 3) sage: H = End(PS) sage: f = H([y^2, x^2, w^2, z^2]) sage: X = PS.subscheme([z^2+y*w, x-w]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Integer Ring defined by: y - z, x*z - w^2 :: sage: PS.<x,y,z,w> = ProjectiveSpace(CC, 3) sage: H = End(PS) sage: f = H([x^2 + y^2, y^2, z^2-y^2, w^2]) sage: X = PS.subscheme([z-2*w]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Complex Field with 53 bits of precision defined by: y + z + (-4.00000000000000)*w :: sage: R.<t> = PolynomialRing(QQ) sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2) sage: H = End(P) sage: f = H([x^2 + 2*y*z, t^2*y^2, z^2]) sage: f([t^2*y-z]) Closed subscheme of Projective Space of dimension 2 over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by: y + (-1/t^2)*z :: sage: set_verbose(-1) sage: PS.<x,y,z> = ProjectiveSpace(Qp(3), 2) sage: H = End(PS) sage: f = H([x^2,2*y^2,z^2]) sage: X = PS.subscheme([2*x-y,z]) sage: f(X) Closed subscheme of Projective Space of dimension 2 over 3-adic Field with capped relative precision 20 defined by: z, x + (1 + 3^2 + 3^4 + 3^6 + 3^8 + 3^10 + 3^12 + 3^14 + 3^16 + 3^18 + O(3^20))*y :: sage: R.<y0,y1,y2,y3> = PolynomialRing(QQ) sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2) sage: H = End(P) sage: f = H([y0*x^2+y1*z^2, y2*y^2+y3*z^2, z^2]) sage: X = P.subscheme(x*z) sage: X._forward_image(f) Closed subscheme of Projective Space of dimension 2 over Fraction Field of Multivariate Polynomial Ring in y0, y1, y2, y3 over Rational Field defined by: x*z + (-y1)*z^2 :: sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2) sage: P5.<z0,z1,z2,z3,z4,z5> = ProjectiveSpace(QQ, 5) sage: H = Hom(P2, P5) sage: f = H([x^2,x*y,x*z,y^2,y*z,z^2]) #Veronese map sage: X = P2.subscheme([]) sage: f(X) Closed subscheme of Projective Space of dimension 5 over Rational Field defined by: -z4^2 + z3*z5, -z2*z4 + z1*z5, -z2*z3 + z1*z4, -z2^2 + z0*z5, -z1*z2 + z0*z4, -z1^2 + z0*z3 :: sage: P2.<x,y,z>=ProjectiveSpace(QQ, 2) sage: P3.<u,v,w,t>=ProjectiveSpace(QQ, 3) sage: H = Hom(P2, P3) sage: X = P2.subscheme([x-y,x-z]) sage: f = H([x^2,y^2,z^2,x*y]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: w - t, v - t, u - t :: sage: P1.<u,v> = ProjectiveSpace(QQ, 1) sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2) sage: H = Hom(P2,P1) sage: f = H([x^2,y*z]) sage: X = P2.subscheme([x-y]) sage: f(X) Traceback (most recent call last): ... TypeError: map must be a morphism :: sage: PS.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: H = End(PS) sage: f = H([x^3, x*y^2, x*z^2]) sage: X = PS.subscheme([x-y]) sage: X._forward_image(f) Traceback (most recent call last): ... TypeError: map must be a morphism :: sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2) sage: P1.<u,v> = ProjectiveSpace(QQ, 1) sage: Y = P1.subscheme([u-v]) sage: H = End(PS) sage: f = H([x^2, y^2, z^2]) sage: Y._forward_image(f) Traceback (most recent call last): ... TypeError: subscheme must be in ambient space of domain of map """ dom = f.domain() codom = f.codomain() if check: if not f.is_morphism(): raise TypeError("map must be a morphism") if self.ambient_space() != dom: raise TypeError("subscheme must be in ambient space of domain of map") CR_dom = dom.coordinate_ring() CR_codom = codom.coordinate_ring() n = CR_dom.ngens() m = CR_codom.ngens() #can't call eliminate if the base ring is polynomial so we do it ourselves #with a lex ordering R = PolynomialRing(f.base_ring(), n+m, 'tempvar', order = 'lex') Rvars = R.gens()[0 : n] phi = CR_dom.hom(Rvars,R) zero = n*[0] psi = R.hom(zero + list(CR_codom.gens()),CR_codom) #set up ideal L = R.ideal([phi(t) for t in self.defining_polynomials()] + [R.gen(n+i) - phi(f[i]) for i in range(m)]) G = L.groebner_basis() #eliminate newL = [] #get only the elimination ideal portion for i in range (len(G)-1,0,-1): v = G[i].variables() if all([Rvars[j] not in v for j in range(n)]): newL.append(psi(G[i])) return(codom.subscheme(newL))
def Chow_form(self): r""" Returns the Chow form associated to this subscheme. For a `k`-dimensional subvariety of `\mathbb{P}^N` of degree `D`. The `(N-k-1)`-dimensional projective linear subspaces of `\mathbb{P}^N` meeting `X` form a hypersurface in the Grassmannian `G(N-k-1,N)`. The homogeneous form of degree `D` defining this hypersurface in Plucker coordinates is called the Chow form of `X`. The base ring needs to be a number field, finite field, or `\QQbar`. ALGORITHM: For a `k`-dimension subscheme `X` consider the `k+1` linear forms `l_i = u_{i0}x_0 + \cdots + u_{in}x_n`. Let `J` be the ideal in the polynomial ring `K[x_i,u_{ij}]` defined by the equations of `X` and the `l_i`. Let `J'` be the saturation of `J` with respect to the irrelevant ideal of the ambient projective space of `X`. The elimination ideal `I = J' \cap K[u_{ij}]` is a principal ideal, let `R` be its generator. The Chow form is obtained by writing `R` as a polynomial in Plucker coordinates (i.e. bracket polynomials). [DalbecSturmfels]_. OUTPUT: a homogeneous polynomial. REFERENCES: .. [DalbecSturmfels] J. Dalbec and B. Sturmfels. Invariant methods in discrete and computational geometry, chapter Introduction to Chow forms, pages 37-58. Springer Netherlands, 1994. EXAMPLES:: sage: P.<x0,x1,x2,x3> = ProjectiveSpace(GF(17), 3) sage: X = P.subscheme([x3+x1,x2-x0,x2-x3]) sage: X.Chow_form() t0 - t1 + t2 + t3 :: sage: P.<x0,x1,x2,x3> = ProjectiveSpace(QQ,3) sage: X = P.subscheme([x3^2 -101*x1^2 - 3*x2*x0]) sage: X.Chow_form() t0^2 - 101*t2^2 - 3*t1*t3 :: sage: P.<x0,x1,x2,x3>=ProjectiveSpace(QQ,3) sage: X = P.subscheme([x0*x2-x1^2, x0*x3-x1*x2, x1*x3-x2^2]) sage: Ch = X.Chow_form(); Ch t2^3 + 2*t2^2*t3 + t2*t3^2 - 3*t1*t2*t4 - t1*t3*t4 + t0*t4^2 + t1^2*t5 sage: Y = P.subscheme_from_Chow_form(Ch, 1); Y Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: x2^2*x3 - x1*x3^2, -x2^3 + x0*x3^2, -x2^2*x3 + x1*x3^2, x1*x2*x3 - x0*x3^2, 3*x1*x2^2 - 3*x0*x2*x3, -2*x1^2*x3 + 2*x0*x2*x3, -3*x1^2*x2 + 3*x0*x1*x3, x1^3 - x0^2*x3, x2^3 - x1*x2*x3, -3*x1*x2^2 + 2*x1^2*x3 + x0*x2*x3, 2*x0*x2^2 - 2*x0*x1*x3, 3*x1^2*x2 - 2*x0*x2^2 - x0*x1*x3, -x0*x1*x2 + x0^2*x3, -x0*x1^2 + x0^2*x2, -x1^3 + x0*x1*x2, x0*x1^2 - x0^2*x2 sage: I = Y.defining_ideal() sage: I.saturation(I.ring().ideal(list(I.ring().gens())))[0] Ideal (x2^2 - x1*x3, x1*x2 - x0*x3, x1^2 - x0*x2) of Multivariate Polynomial Ring in x0, x1, x2, x3 over Rational Field """ I = self.defining_ideal() P = self.ambient_space() R = P.coordinate_ring() N = P.dimension()+1 d = self.dimension() #create the ring for the generic linear hyperplanes # u0x0 + u1x1 + ... SS = PolynomialRing(R.base_ring(), 'u', N*(d+1), order='lex') vars = SS.variable_names() + R.variable_names() S = PolynomialRing(R.base_ring(), vars, order='lex') n = S.ngens() newcoords = [S.gen(n-N+t) for t in range(N)] #map the generators of the subscheme into the ring with the hyperplane variables phi = R.hom(newcoords,S) phi(self.defining_polynomials()[0]) #create the dim(X)+1 linear hyperplanes l = [] for i in range(d+1): t = 0 for j in range(N): t += S.gen(N*i + j)*newcoords[j] l.append(t) #intersect the hyperplanes with X J = phi(I) + S.ideal(l) #saturate the ideal with respect to the irrelevant ideal J2 = J.saturation(S.ideal([phi(t) for t in R.gens()]))[0] #eliminate the original variables to be left with the hyperplane coefficients 'u' E = J2.elimination_ideal(newcoords) #create the plucker coordinates D = binomial(N,N-d-1) #number of plucker coordinates tvars = [str('t') + str(i) for i in range(D)] #plucker coordinates T = PolynomialRing(R.base_ring(), tvars+list(S.variable_names()), order='lex') L = [] coeffs = [T.gen(i) for i in range(0+len(tvars), N*(d+1)+len(tvars))] M = matrix(T,d+1,N,coeffs) i = 0 for c in M.minors(d+1): L.append(T.gen(i)-c) i += 1 #create the ideal that we can use for eliminating to get a polynomial #in the plucker coordinates (brackets) br = T.ideal(L) #create a mapping into a polynomial ring over the plucker coordinates #and the hyperplane coefficients psi = S.hom(coeffs + [0 for i in range(N)],T) E2 = T.ideal([psi(u) for u in E.gens()] +br) #eliminate the hyperplane coefficients CH = E2.elimination_ideal(coeffs) #CH should be a principal ideal, but because of the relations among #the plucker coordinates, the elimination will probably have several generators #get the relations among the plucker coordinates rel = br.elimination_ideal(coeffs) #reduce CH with respect to the relations reduced = [] for f in CH.gens(): reduced.append(f.reduce(rel)) #find the principal generator #polynomial ring in just the plucker coordinates T2 = PolynomialRing(R.base_ring(), tvars) alp = T.hom(tvars + (N*(d+1) +N)*[0], T2) #get the degrees of the reduced generators of CH degs = [u.degree() for u in reduced] mind = max(degs) #need the smallest degree form that did not reduce to 0 for d in degs: if d < mind and d >0: mind = d ind = degs.index(mind) CF = reduced[ind] #this should be the Chow form of X #check that it is correct (i.e., it is a principal generator for CH + the relations) rel2 = rel + [CF] assert all([f in rel2 for f in CH.gens()]), "did not find a principal generator" return(alp(CF))
def homogenize(self,n,newvar='h'): r""" Return the homogenization of ``self``. If ``self.domain()`` is a subscheme, the domain of the homogenized map is the projective embedding of ``self.domain()``. The domain and codomain can be homogenized at different coordinates: ``n[0]`` for the domain and ``n[1]`` for the codomain. INPUT: - ``newvar`` -- the name of the homogenization variable (only used when ``self.domain()`` is affine space) - ``n`` -- a tuple of nonnegative integers. If ``n`` is an integer, then the two values of the tuple are assumed to be the same. OUTPUT: - :class:`SchemMorphism_polynomial_projective_space` EXAMPLES:: sage: A.<x,y>=AffineSpace(ZZ,2) sage: H=Hom(A,A) sage: f=H([(x^2-2)/x^5,y^2]) sage: f.homogenize(2,'z') Scheme endomorphism of Projective Space of dimension 2 over Integer Ring Defn: Defined on coordinates by sending (x : y : z) to (x^2*z^5 - 2*z^7 : x^5*y^2 : x^5*z^2) :: sage: A.<x,y>=AffineSpace(CC,2) sage: H=Hom(A,A) sage: f=H([(x^2-2)/(x*y),y^2-x]) sage: f.homogenize((2,0),'z') Scheme endomorphism of Projective Space of dimension 2 over Complex Field with 53 bits of precision Defn: Defined on coordinates by sending (x : y : z) to (x*y*z^2 : x^2*z^2 + (-2.00000000000000)*z^4 : x*y^3 - x^2*y*z) :: sage: A.<x,y>=AffineSpace(ZZ,2) sage: X=A.subscheme([x-y^2]) sage: H=Hom(X,X) sage: f=H([9*y^2,3*y]) sage: f.homogenize(2) Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 over Integer Ring defined by: -x1^2 + x0*x2 Defn: Defined on coordinates by sending (x0 : x1 : x2) to (9*x0*x2 : 3*x1*x2 : x2^2) :: sage: R.<t>=PolynomialRing(ZZ) sage: A.<x,y>=AffineSpace(R,2) sage: H=Hom(A,A) sage: f=H([(x^2-2)/y,y^2-x]) sage: f.homogenize((2,0),'z') Scheme endomorphism of Projective Space of dimension 2 over Univariate Polynomial Ring in t over Integer Ring Defn: Defined on coordinates by sending (x : y : z) to (y*z^2 : x^2*z + (-2)*z^3 : y^3 - x*y*z) :: sage: A.<x>=AffineSpace(QQ,1) sage: H=End(A) sage: f=H([x^2-1]) sage: f.homogenize((1,0),'y') Scheme endomorphism of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y) to (y^2 : x^2 - y^2) """ A=self.domain() B=self.codomain() N=A.ambient_space().dimension_relative() NB=B.ambient_space().dimension_relative() #it is possible to homogenize the domain and codomain at different coordinates if isinstance(n,(tuple,list)): ind=tuple(n) else: ind=(n,n) #homogenize the domain Vars=list(A.ambient_space().variable_names()) Vars.insert(ind[0],newvar) S=PolynomialRing(A.base_ring(),Vars) #find the denominators if a rational function try: l=lcm([self[i].denominator() for i in range(N)]) except Exception: #no lcm l=prod([self[i].denominator() for i in range(N)]) from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.multi_polynomial_ring_generic import MPolynomialRing_generic if self.domain().base_ring()==RealField() or self.domain().base_ring()==ComplexField(): F=[S(((self[i]*l).numerator())._maxima_().divide(self[i].denominator())[0].sage()) for i in range(N)] elif isinstance(self.domain().base_ring(),(PolynomialRing_general,MPolynomialRing_generic)): F=[S(((self[i]*l).numerator())._maxima_().divide(self[i].denominator())[0].sage()) for i in range(N)] else: F=[S(self[i]*l) for i in range(N)] #homogenize the codomain F.insert(ind[1],S(l)) d=max([F[i].degree() for i in range(N+1)]) F=[F[i].homogenize(newvar)*S.gen(N)**(d-F[i].degree()) for i in range(N+1)] from sage.schemes.affine.affine_space import is_AffineSpace if is_AffineSpace(A)==True: from sage.schemes.projective.projective_space import ProjectiveSpace X=ProjectiveSpace(A.base_ring(),NB,Vars) else: X=A.projective_embedding(ind[1]).codomain() phi=S.hom(X.ambient_space().gens(),X.ambient_space().coordinate_ring()) F=[phi(f) for f in F] H=Hom(X,X) return(H(F))
def homogenize(self, n, newvar='h'): r""" Return the homogenization of ``self``. If ``self.domain()`` is a subscheme, the domain of the homogenized map is the projective embedding of ``self.domain()`` INPUT: - ``newvar`` -- the name of the homogenization variable (only used when ``self.domain()`` is affine space) - ``n`` -- the n-th projective embedding into projective space OUTPUT: - :class:`SchemMorphism_polynomial_projective_space` EXAMPLES:: sage: A.<x,y>=AffineSpace(ZZ,2) sage: H=Hom(A,A) sage: f=H([(x^2-2)/x^5,y^2]) sage: f.homogenize(2,'z') Scheme endomorphism of Projective Space of dimension 2 over Integer Ring Defn: Defined on coordinates by sending (x : y : z) to (x^2*z^5 - 2*z^7 : x^5*y^2 : x^5*z^2) :: sage: A.<x,y>=AffineSpace(CC,2) sage: H=Hom(A,A) sage: f=H([(x^2-2)/(x*y),y^2-x]) sage: f.homogenize(0,'z') Scheme endomorphism of Projective Space of dimension 2 over Complex Field with 53 bits of precision Defn: Defined on coordinates by sending (x : y : z) to (x*y*z^2 : x^2*z^2 + (-2.00000000000000)*z^4 : x*y^3 - x^2*y*z) :: sage: A.<x,y>=AffineSpace(ZZ,2) sage: X=A.subscheme([x-y^2]) sage: H=Hom(X,X) sage: f=H([9*y^2,3*y]) sage: f.homogenize(2) Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 over Integer Ring defined by: -x1^2 + x0*x2 Defn: Defined on coordinates by sending (x0 : x1 : x2) to (9*x0*x2 : 3*x1*x2 : x2^2) :: sage: R.<t>=PolynomialRing(ZZ) sage: A.<x,y>=AffineSpace(R,2) sage: H=Hom(A,A) sage: f=H([(x^2-2)/y,y^2-x]) sage: f.homogenize(0,'z') Scheme endomorphism of Projective Space of dimension 2 over Univariate Polynomial Ring in t over Integer Ring Defn: Defined on coordinates by sending (x : y : z) to (y*z^2 : x^2*z + (-2)*z^3 : y^3 - x*y*z) """ A = self.domain() B = self.codomain() N = A.ambient_space().dimension_relative() NB = B.ambient_space().dimension_relative() Vars = list(A.ambient_space().variable_names()) + [newvar] S = PolynomialRing(A.base_ring(), Vars) try: l = lcm([self[i].denominator() for i in range(N)]) except Exception: #no lcm l = prod([self[i].denominator() for i in range(N)]) from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.multi_polynomial_ring_generic import MPolynomialRing_generic if self.domain().base_ring() == RealField() or self.domain().base_ring( ) == ComplexField(): F = [ S(((self[i] * l).numerator())._maxima_().divide( self[i].denominator())[0].sage()) for i in range(N) ] elif isinstance(self.domain().base_ring(), (PolynomialRing_general, MPolynomialRing_generic)): F = [ S(((self[i] * l).numerator())._maxima_().divide( self[i].denominator())[0].sage()) for i in range(N) ] else: F = [S(self[i] * l) for i in range(N)] F.insert(n, S(l)) d = max([F[i].degree() for i in range(N + 1)]) F = [ F[i].homogenize(newvar) * S.gen(N)**(d - F[i].degree()) for i in range(N + 1) ] from sage.schemes.affine.affine_space import is_AffineSpace if is_AffineSpace(A) == True: from sage.schemes.projective.projective_space import ProjectiveSpace X = ProjectiveSpace(A.base_ring(), NB, Vars) else: X = A.projective_embedding(n).codomain() phi = S.hom(X.ambient_space().gens(), X.ambient_space().coordinate_ring()) F = [phi(f) for f in F] H = Hom(X, X) return (H(F))
def make_function_field(K): r""" Return the function field isomorphic to this field, an isomorphism, and its inverse. INPUT: - ``K`` -- a field OUTPUT: A triple `(F,\phi,\psi)`, where `F` is a rational function field, `\phi:K\to F` is a field isomorphism and `\psi` the inverse of `\phi`. It is assumed that `K` is either the fraction field of a polynomial ring over a finite field `k`, or a finite simple extension of such a field. In the first case, `F=k_1(x)` is a rational function field over a finite field `k_1`, where `k_1` as an *absolute* finite field isomorphic to `k`. In the second case, `F` is a finite simple extension of a rational function field as in the first case. """ from mclf.curves.smooth_projective_curves import make_finite_field from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.categories.function_fields import FunctionFields if hasattr(K, "modulus") or hasattr(K, "polynomial"): # we hope that K is a simple finite extension of a field which is # isomorphic to a rational function field K_base = K.base_field() F_base, phi_base, psi_base = make_function_field(K_base) if hasattr(K, "modulus"): G = K.modulus() else: G = K.polynomial() R = G.parent() R_new = PolynomialRing(F_base, R.variable_name()) G_new = R_new([phi_base(c) for c in G.list()]) assert G_new.is_irreducible(), "G must be irreducible!" # F = F_base.extension(G_new, R.variable_name()) F = F_base.extension(G_new, 'y') # phi0 = R.hom(F.gen(), F) # to construct phi:K=K_0[x]/(G) --> F=F_0[y]/(G), # we first 'map' from K to K_0[x] phi = K.hom(R.gen(), R, check=False) # then from K_0[x] to F_0[y] psi = R.hom(phi_base, R_new) # then from F_0[y] to F = F_0[y]/(G) phi = phi.post_compose(psi.post_compose(R_new.hom(F.gen(), F))) psi = F.hom(K.gen(), psi_base) return F, phi, psi else: # we hope that K is isomorphic to a rational function field over a # finite field if K in FunctionFields(): # K is already a function field k = K.constant_base_field() k_new, phi_base, psi_base = make_finite_field(k) F = FunctionField(k_new, K.variable_name()) phi = K.hom(F.gen(), phi_base) psi = F.hom(K.gen(), psi_base) return F, phi, psi elif hasattr(K, "function_field"): F1 = K.function_field() phi1 = F1.coerce_map_from(K) psi1 = F1.hom(K.gen()) F, phi2, psi2 = make_function_field(F1) phi = phi1.post_compose(phi2) psi = psi2.post_compose(psi1) return F, phi, psi else: raise NotImplementedError