def HammingCode(r,F): r""" Implements the Hamming codes. The `r^{th}` Hamming code over `F=GF(q)` is an `[n,k,d]` code with length `n=(q^r-1)/(q-1)`, dimension `k=(q^r-1)/(q-1) - r` and minimum distance `d=3`. The parity check matrix of a Hamming code has rows consisting of all nonzero vectors of length r in its columns, modulo a scalar factor so no parallel columns arise. A Hamming code is a single error-correcting code. INPUT: - ``r`` - an integer 2 - ``F`` - a finite field. OUTPUT: Returns the r-th q-ary Hamming code. EXAMPLES:: sage: HammingCode(3,GF(2)) Linear code of length 7, dimension 4 over Finite Field of size 2 sage: C = HammingCode(3,GF(3)); C Linear code of length 13, dimension 10 over Finite Field of size 3 sage: C.minimum_distance() 3 sage: C.minimum_distance(algorithm='gap') # long time, check d=3 3 sage: C = HammingCode(3,GF(4,'a')); C Linear code of length 21, dimension 18 over Finite Field in a of size 2^2 """ q = F.order() n = (q**r-1)/(q-1) k = n-r MS = MatrixSpace(F,n,r) X = ProjectiveSpace(r-1,F) PFn = [list(p) for p in X.point_set(F).points(F)] H = MS(PFn).transpose() Cd = LinearCode(H) # Hamming code always has distance 3, so we provide the distance. return LinearCode(Cd.dual_code().gen_mat(), d=3)
def HammingCode(r, F): r""" Implements the Hamming codes. The `r^{th}` Hamming code over `F=GF(q)` is an `[n,k,d]` code with length `n=(q^r-1)/(q-1)`, dimension `k=(q^r-1)/(q-1) - r` and minimum distance `d=3`. The parity check matrix of a Hamming code has rows consisting of all nonzero vectors of length r in its columns, modulo a scalar factor so no parallel columns arise. A Hamming code is a single error-correcting code. INPUT: - ``r`` - an integer 2 - ``F`` - a finite field. OUTPUT: Returns the r-th q-ary Hamming code. EXAMPLES:: sage: HammingCode(3,GF(2)) Linear code of length 7, dimension 4 over Finite Field of size 2 sage: C = HammingCode(3,GF(3)); C Linear code of length 13, dimension 10 over Finite Field of size 3 sage: C.minimum_distance() 3 sage: C.minimum_distance(algorithm='gap') # long time, check d=3 3 sage: C = HammingCode(3,GF(4,'a')); C Linear code of length 21, dimension 18 over Finite Field in a of size 2^2 """ q = F.order() n = (q**r - 1) / (q - 1) k = n - r MS = MatrixSpace(F, n, r) X = ProjectiveSpace(r - 1, F) PFn = [list(p) for p in X.point_set(F).points(F)] H = MS(PFn).transpose() Cd = LinearCode(H) # Hamming code always has distance 3, so we provide the distance. return LinearCode(Cd.dual_code().gen_mat(), d=3)
def projective_embedding(self, i=None, PP=None): """ Returns a morphism from this space into an ambient projective space of the same dimension. INPUT: - ``i`` - integer (default: dimension of self = last coordinate) determines which projective embedding to compute. The embedding is that which has a 1 in the i-th coordinate, numbered from 0. - ``PP`` - (default: None) ambient projective space, i.e., codomain of morphism; this is constructed if it is not given. EXAMPLES:: sage: AA = AffineSpace(2, QQ, 'x') sage: pi = AA.projective_embedding(0); pi Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x0, x1) to (1 : x0 : x1) sage: z = AA(3,4) sage: pi(z) (1/4 : 3/4 : 1) sage: pi(AA(0,2)) (1/2 : 0 : 1) sage: pi = AA.projective_embedding(1); pi Scheme morphism: From: Affine Space of dimension 2 over Rational Field To: Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x0, x1) to (x0 : 1 : x1) sage: pi(z) (3/4 : 1/4 : 1) sage: pi = AA.projective_embedding(2) sage: pi(z) (3 : 4 : 1) """ n = self.dimension_relative() if i is None: try: i = self._default_embedding_index except AttributeError: i = int(n) else: i = int(i) try: return self.__projective_embedding[i] except AttributeError: self.__projective_embedding = {} except KeyError: pass if PP is None: from sage.schemes.generic.projective_space import ProjectiveSpace PP = ProjectiveSpace(n, self.base_ring()) R = self.coordinate_ring() v = list(R.gens()) if n < 0 or n >self.dimension_relative(): raise ValueError, \ "Argument i (=%s) must be between 0 and %s, inclusive"%(i,n) v.insert(i, R(1)) phi = self.hom(v, PP) self.__projective_embedding[i] = phi return phi
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. 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. 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)