def parametrization(self, point=None, morphism=True): r""" Return a parametrization `f` of ``self`` together with the inverse of `f`. If ``point`` is specified, then that point is used for the parametrization. Otherwise, use ``self.rational_point()`` to find a point. If ``morphism`` is True, then `f` is returned in the form of a Scheme morphism. Otherwise, it is a tuple of polynomials that gives the parametrization. EXAMPLES: An example over a finite field :: sage: c = Conic(GF(2), [1,1,1,1,1,0]) sage: c.parametrization() (Scheme morphism: From: Projective Space of dimension 1 over Finite Field of size 2 To: Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y + y^2 + x*z + y*z Defn: Defined on coordinates by sending (x : y) to (x*y + y^2 : x^2 + x*y : x^2 + x*y + y^2), Scheme morphism: From: Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y + y^2 + x*z + y*z To: Projective Space of dimension 1 over Finite Field of size 2 Defn: Defined on coordinates by sending (x : y : z) to (y : x)) An example with ``morphism = False`` :: sage: R.<x,y,z> = QQ[] sage: C = Curve(7*x^2 + 2*y*z + z^2) sage: (p, i) = C.parametrization(morphism = False); (p, i) ([-2*x*y, 7*x^2 + y^2, -2*y^2], [-1/2*x, -1/2*z]) sage: C.defining_polynomial()(p) 0 sage: i[0](p) / i[1](p) x/y A ``ValueError`` is raised if ``self`` has no rational point :: sage: C = Conic(x^2 + y^2 + 7*z^2) sage: C.parametrization() Traceback (most recent call last): ... ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + 7*z^2 has no rational points over Rational Field! A ``ValueError`` is raised if ``self`` is not smooth :: sage: C = Conic(x^2 + y^2) sage: C.parametrization() Traceback (most recent call last): ... ValueError: The conic self (=Projective Conic Curve over Rational Field defined by x^2 + y^2) is not smooth, hence does not have a parametrization. """ if (not self._parametrization is None) and not point: par = self._parametrization else: if not self.is_smooth(): raise ValueError, "The conic self (=%s) is not smooth, hence does not have a parametrization." % self if point == None: point = self.rational_point() point = Sequence(point) B = self.base_ring() Q = PolynomialRing(B, 'x,y') [x, y] = Q.gens() gens = self.ambient_space().gens() P = PolynomialRing(B, 4, ['X', 'Y', 'T0', 'T1']) [X, Y, T0, T1] = P.gens() c3 = [j for j in range(2,-1,-1) if point[j] != 0][0] c1 = [j for j in range(3) if j != c3][0] c2 = [j for j in range(3) if j != c3 and j != c1][0] L = [0,0,0] L[c1] = Y*T1*point[c1] + Y*T0 L[c2] = Y*T1*point[c2] + X*T0 L[c3] = Y*T1*point[c3] bezout = P(self.defining_polynomial()(L) / T0) t = [bezout([x,y,0,-1]),bezout([x,y,1,0])] par = (tuple([Q(p([x,y,t[0],t[1]])/y) for p in L]), tuple([gens[m]*point[c3]-gens[c3]*point[m] for m in [c2,c1]])) if self._parametrization is None: self._parametrization = par if not morphism: return par P1 = ProjectiveSpace(self.base_ring(), 1, 'x,y') return P1.hom(par[0],self), self.Hom(P1)(par[1], check = False)
def parametrization(self, point=None, morphism=True): r""" Return a parametrization `f` of ``self`` together with the inverse of `f`. If ``point`` is specified, then that point is used for the parametrization. Otherwise, use ``self.rational_point()`` to find a point. If ``morphism`` is True, then `f` is returned in the form of a Scheme morphism. Otherwise, it is a tuple of polynomials that gives the parametrization. ALGORITHM: Uses Denis Simon's pari script Qfparam. See ``sage.quadratic_forms.qfsolve.qfparam``. EXAMPLES :: sage: c = Conic([1,1,-1]) sage: c.parametrization() (Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2 Defn: Defined on coordinates by sending (x : y) to (2*x*y : x^2 - y^2 : x^2 + y^2), Scheme morphism: From: Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2 To: Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y : z) to (1/2*x : -1/2*y + 1/2*z)) An example with ``morphism = False`` :: sage: R.<x,y,z> = QQ[] sage: C = Curve(7*x^2 + 2*y*z + z^2) sage: (p, i) = C.parametrization(morphism = False); (p, i) ([-2*x*y, 7*x^2 + y^2, -2*y^2], [-1/2*x, -1/2*z]) sage: C.defining_polynomial()(p) 0 sage: i[0](p) / i[1](p) x/y A ``ValueError`` is raised if ``self`` has no rational point :: sage: C = Conic(x^2 + 2*y^2 + z^2) sage: C.parametrization() Traceback (most recent call last): ... ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + z^2 has no rational points over Rational Field! A ``ValueError`` is raised if ``self`` is not smooth :: sage: C = Conic(x^2 + y^2) sage: C.parametrization() Traceback (most recent call last): ... ValueError: The conic self (=Projective Conic Curve over Rational Field defined by x^2 + y^2) is not smooth, hence does not have a parametrization. """ if (not self._parametrization is None) and not point: par = self._parametrization else: if not self.is_smooth(): raise ValueError, "The conic self (=%s) is not smooth, hence does not have a parametrization." % self if point == None: point = self.rational_point() point = Sequence(point) Q = PolynomialRing(QQ, 'x,y') [x, y] = Q.gens() gens = self.ambient_space().gens() M = self.symmetric_matrix() M *= lcm([t.denominator() for t in M.list()]) par1 = qfparam(M, point) B = Matrix([[par1[i][j] for j in range(3)] for i in range(3)]) # self is in the image of B and does not lie on a line, # hence B is invertible A = B.inverse() par2 = [sum([A[i, j] * gens[j] for j in range(3)]) for i in [1, 0]] par = ([Q(pol(x / y) * y**2) for pol in par1], par2) if self._parametrization is None: self._parametrization = par if not morphism: return par P1 = ProjectiveSpace(self.base_ring(), 1, 'x,y') return P1.hom(par[0], self), self.Hom(P1)(par[1], check=False)
def parametrization(self, point=None, morphism=True): r""" Return a parametrization `f` of ``self`` together with the inverse of `f`. If ``point`` is specified, then that point is used for the parametrization. Otherwise, use ``self.rational_point()`` to find a point. If ``morphism`` is True, then `f` is returned in the form of a Scheme morphism. Otherwise, it is a tuple of polynomials that gives the parametrization. EXAMPLES: An example over a finite field :: sage: c = Conic(GF(2), [1,1,1,1,1,0]) sage: c.parametrization() (Scheme morphism: From: Projective Space of dimension 1 over Finite Field of size 2 To: Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y + y^2 + x*z + y*z Defn: Defined on coordinates by sending (x : y) to (x*y + y^2 : x^2 + x*y : x^2 + x*y + y^2), Scheme morphism: From: Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y + y^2 + x*z + y*z To: Projective Space of dimension 1 over Finite Field of size 2 Defn: Defined on coordinates by sending (x : y : z) to (y : x)) An example with ``morphism = False`` :: sage: R.<x,y,z> = QQ[] sage: C = Curve(7*x^2 + 2*y*z + z^2) sage: (p, i) = C.parametrization(morphism = False); (p, i) ([-2*x*y, 7*x^2 + y^2, -2*y^2], [-1/2*x, -1/2*z]) sage: C.defining_polynomial()(p) 0 sage: i[0](p) / i[1](p) x/y A ``ValueError`` is raised if ``self`` has no rational point :: sage: C = Conic(x^2 + y^2 + 7*z^2) sage: C.parametrization() Traceback (most recent call last): ... ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + 7*z^2 has no rational points over Rational Field! A ``ValueError`` is raised if ``self`` is not smooth :: sage: C = Conic(x^2 + y^2) sage: C.parametrization() Traceback (most recent call last): ... ValueError: The conic self (=Projective Conic Curve over Rational Field defined by x^2 + y^2) is not smooth, hence does not have a parametrization. """ if (not self._parametrization is None) and not point: par = self._parametrization else: if not self.is_smooth(): raise ValueError, "The conic self (=%s) is not smooth, hence does not have a parametrization." % self if point == None: point = self.rational_point() point = Sequence(point) B = self.base_ring() Q = PolynomialRing(B, 'x,y') [x, y] = Q.gens() gens = self.ambient_space().gens() P = PolynomialRing(B, 4, ['X', 'Y', 'T0', 'T1']) [X, Y, T0, T1] = P.gens() c3 = [j for j in range(2, -1, -1) if point[j] != 0][0] c1 = [j for j in range(3) if j != c3][0] c2 = [j for j in range(3) if j != c3 and j != c1][0] L = [0, 0, 0] L[c1] = Y * T1 * point[c1] + Y * T0 L[c2] = Y * T1 * point[c2] + X * T0 L[c3] = Y * T1 * point[c3] bezout = P(self.defining_polynomial()(L) / T0) t = [bezout([x, y, 0, -1]), bezout([x, y, 1, 0])] par = (tuple([Q(p([x, y, t[0], t[1]]) / y) for p in L]), tuple([ gens[m] * point[c3] - gens[c3] * point[m] for m in [c2, c1] ])) if self._parametrization is None: self._parametrization = par if not morphism: return par P1 = ProjectiveSpace(self.base_ring(), 1, 'x,y') return P1.hom(par[0], self), self.Hom(P1)(par[1], check=False)
def parametrization(self, point=None, morphism=True): r""" Return a parametrization `f` of ``self`` together with the inverse of `f`. If ``point`` is specified, then that point is used for the parametrization. Otherwise, use ``self.rational_point()`` to find a point. If ``morphism`` is True, then `f` is returned in the form of a Scheme morphism. Otherwise, it is a tuple of polynomials that gives the parametrization. ALGORITHM: Uses Denis Simon's pari script Qfparam. See ``sage.quadratic_forms.qfsolve.qfparam``. EXAMPLES :: sage: c = Conic([1,1,-1]) sage: c.parametrization() (Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2 Defn: Defined on coordinates by sending (x : y) to (2*x*y : x^2 - y^2 : x^2 + y^2), Scheme morphism: From: Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2 To: Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y : z) to (1/2*x : -1/2*y + 1/2*z)) An example with ``morphism = False`` :: sage: R.<x,y,z> = QQ[] sage: C = Curve(7*x^2 + 2*y*z + z^2) sage: (p, i) = C.parametrization(morphism = False); (p, i) ([-2*x*y, 7*x^2 + y^2, -2*y^2], [-1/2*x, -1/2*z]) sage: C.defining_polynomial()(p) 0 sage: i[0](p) / i[1](p) x/y A ``ValueError`` is raised if ``self`` has no rational point :: sage: C = Conic(x^2 + 2*y^2 + z^2) sage: C.parametrization() Traceback (most recent call last): ... ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + z^2 has no rational points over Rational Field! A ``ValueError`` is raised if ``self`` is not smooth :: sage: C = Conic(x^2 + y^2) sage: C.parametrization() Traceback (most recent call last): ... ValueError: The conic self (=Projective Conic Curve over Rational Field defined by x^2 + y^2) is not smooth, hence does not have a parametrization. """ if (not self._parametrization is None) and not point: par = self._parametrization else: if not self.is_smooth(): raise ValueError, "The conic self (=%s) is not smooth, hence does not have a parametrization." % self if point == None: point = self.rational_point() point = Sequence(point) Q = PolynomialRing(QQ, 'x,y') [x, y] = Q.gens() gens = self.ambient_space().gens() M = self.symmetric_matrix() M *= lcm([ t.denominator() for t in M.list() ]) par1 = qfparam(M, point) B = Matrix([[par1[i][j] for j in range(3)] for i in range(3)]) # self is in the image of B and does not lie on a line, # hence B is invertible A = B.inverse() par2 = [sum([A[i,j]*gens[j] for j in range(3)]) for i in [1,0]] par = ([Q(pol(x/y)*y**2) for pol in par1], par2) if self._parametrization is None: self._parametrization = par if not morphism: return par P1 = ProjectiveSpace(self.base_ring(), 1, 'x,y') return P1.hom(par[0],self), self.Hom(P1)(par[1], check = False)