Path: blob/master/sage/schemes/plane_conics/con_finite_field.py
4108 views
r"""1Projective plane conics over finite fields23AUTHORS:45- Marco Streng (2010-07-20)67"""8#*****************************************************************************9# Copyright (C) 2009/2010 Marco Streng <[email protected]>10#11# Distributed under the terms of the GNU General Public License (GPL)12#13# This code is distributed in the hope that it will be useful,14# but WITHOUT ANY WARRANTY; without even the implied warranty of15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU16# General Public License for more details.17#18# The full text of the GPL is available at:19#20# http://www.gnu.org/licenses/21#*****************************************************************************2223from sage.rings.all import PolynomialRing24from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_finite_field25from con_field import ProjectiveConic_field2627class ProjectiveConic_finite_field(ProjectiveConic_field, ProjectiveCurve_finite_field):28r"""29Create a projective plane conic curve over a finite field.30See ``Conic`` for full documentation.3132EXAMPLES::3334sage: K.<a> = FiniteField(9, 'a')35sage: P.<X, Y, Z> = K[]36sage: Conic(X^2 + Y^2 - a*Z^2)37Projective Conic Curve over Finite Field in a of size 3^2 defined by X^2 + Y^2 + (-a)*Z^23839TESTS::4041sage: K.<a> = FiniteField(4, 'a')42sage: Conic([a, 1, -1])._test_pickling()43"""44def __init__(self, A, f):45r"""46See ``Conic`` for full documentation.4748EXAMPLES ::4950sage: Conic([GF(3)(1), 1, 1])51Projective Conic Curve over Finite Field of size 3 defined by x^2 + y^2 + z^252"""53ProjectiveConic_field.__init__(self, A, f)545556def count_points(self, n):57r"""58If the base field `B` of `self` is finite of order `q`,59then returns the number of points over `\GF{q}, ..., \GF{q^n}`.6061EXAMPLES::6263sage: P.<x,y,z> = GF(3)[]64sage: c = Curve(x^2+y^2+z^2); c65Projective Conic Curve over Finite Field of size 3 defined by x^2 + y^2 + z^266sage: c.count_points(4)67[4, 10, 28, 82]68"""69F = self.base_ring()70q = F.cardinality()71return [q**i+1 for i in range(1, n+1)]727374def has_rational_point(self, point = False, read_cache = True, \75algorithm = 'default'):76r"""77Always returns ``True`` because self has a point defined over78its finite base field `B`.7980If ``point`` is True, then returns a second output `S`, which is a81rational point if one exists.8283Points are cached. If ``read_cache`` is True, then cached information84is used for the output if available. If no cached point is available85or ``read_cache`` is False, then random `y`-coordinates are tried86if ``self`` is smooth and a singular point is returned otherwise.8788EXAMPLES ::8990sage: Conic(FiniteField(37), [1, 2, 3, 4, 5, 6]).has_rational_point()91True9293sage: C = Conic(FiniteField(2), [1, 1, 1, 1, 1, 0]); C94Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y + y^2 + x*z + y*z95sage: C.has_rational_point(point = True) # output is random96(True, (0 : 0 : 1))9798sage: p = next_prime(10^50)99sage: F = FiniteField(p)100sage: C = Conic(F, [1, 2, 3]); C101Projective Conic Curve over Finite Field of size 100000000000000000000000000000000000000000000000151 defined by x^2 + 2*y^2 + 3*z^2102sage: C.has_rational_point(point = True) # output is random103(True,104(14971942941468509742682168602989039212496867586852 : 75235465708017792892762202088174741054630437326388 : 1)105106sage: F.<a> = FiniteField(7^20)107sage: C = Conic([1, a, -5]); C108Projective Conic Curve over Finite Field in a of size 7^20 defined by x^2 + (a)*y^2 + 2*z^2109sage: C.has_rational_point(point = True) # output is random110(True,111(a^18 + 2*a^17 + 4*a^16 + 6*a^13 + a^12 + 6*a^11 + 3*a^10 + 4*a^9 + 2*a^8 + 4*a^7 + a^6 + 4*a^4 + 6*a^2 + 3*a + 6 : 5*a^19 + 5*a^18 + 5*a^17 + a^16 + 2*a^15 + 3*a^14 + 4*a^13 + 5*a^12 + a^11 + 3*a^10 + 2*a^8 + 3*a^7 + 4*a^6 + 4*a^5 + 6*a^3 + 5*a^2 + 2*a + 4 : 1))112113TESTS ::114115sage: l = Sequence(cartesian_product_iterator([[0, 1] for i in range(6)]))116sage: bigF = GF(next_prime(2^100))117sage: bigF2 = GF(next_prime(2^50)^2, 'b')118sage: m = [[F(b) for b in a] for a in l for F in [GF(2), GF(4, 'a'), GF(5), GF(9, 'a'), bigF, bigF2]]119sage: m += [[F.random_element() for i in range(6)] for j in range(20) for F in [GF(5), bigF]]120sage: c = [Conic(a) for a in m if a != [0,0,0,0,0,0]]121sage: assert all([C.has_rational_point() for C in c])122sage: r = randrange(0, 5)123sage: assert all([C.defining_polynomial()(Sequence(C.has_rational_point(point = True)[1])) == 0 for C in c[r::5]]) # long time: 1.6 seconds124"""125if not point:126return True127if read_cache:128if self._rational_point is not None:129return True, self._rational_point130B = self.base_ring()131s, pt = self.has_singular_point(point = True)132if s:133return True, pt134while True:135x = B.random_element()136Y = PolynomialRing(B,'Y').gen()137r = self.defining_polynomial()([x,Y,1]).roots()138if len(r) > 0:139return True, self.point([x,r[0][0],B(1)])140141142143144145