passagemath-schemes 10.6.40__cp314-cp314-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-schemes might be problematic. Click here for more details.
- passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.40.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
- passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.40.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-314-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-314-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-314-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-314-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-314-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-314-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list.cpython-314-darwin.so +0 -0
- sage/modular/modsym/p1list.pxd +29 -0
- sage/modular/modsym/p1list.pyx +1372 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-314-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-314-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-314-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- sage_wheels/share/ellcurves/rank9 +7 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.rings.finite_rings
|
|
3
|
+
r"""
|
|
4
|
+
Projective plane conics over finite fields
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Marco Streng (2010-07-20)
|
|
9
|
+
"""
|
|
10
|
+
# ****************************************************************************
|
|
11
|
+
# Copyright (C) 2009/2010 Marco Streng <marco.streng@gmail.com>
|
|
12
|
+
#
|
|
13
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
14
|
+
#
|
|
15
|
+
# This code is distributed in the hope that it will be useful,
|
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
18
|
+
# General Public License for more details.
|
|
19
|
+
#
|
|
20
|
+
# The full text of the GPL is available at:
|
|
21
|
+
#
|
|
22
|
+
# https://www.gnu.org/licenses/
|
|
23
|
+
# ****************************************************************************
|
|
24
|
+
|
|
25
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
26
|
+
from sage.schemes.curves.projective_curve import ProjectivePlaneCurve_finite_field
|
|
27
|
+
from .con_field import ProjectiveConic_field
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ProjectiveConic_finite_field(ProjectiveConic_field, ProjectivePlaneCurve_finite_field):
|
|
31
|
+
r"""
|
|
32
|
+
Create a projective plane conic curve over a finite field.
|
|
33
|
+
|
|
34
|
+
See ``Conic`` for full documentation.
|
|
35
|
+
|
|
36
|
+
EXAMPLES::
|
|
37
|
+
|
|
38
|
+
sage: K.<a> = FiniteField(9, 'a')
|
|
39
|
+
sage: P.<X, Y, Z> = K[]
|
|
40
|
+
sage: Conic(X^2 + Y^2 - a*Z^2)
|
|
41
|
+
Projective Conic Curve over Finite Field in a of size 3^2
|
|
42
|
+
defined by X^2 + Y^2 + (-a)*Z^2
|
|
43
|
+
|
|
44
|
+
::
|
|
45
|
+
|
|
46
|
+
sage: P.<X, Y, Z> = FiniteField(5)[]
|
|
47
|
+
sage: Conic(X^2 + Y^2 - 2*Z^2)
|
|
48
|
+
Projective Conic Curve over Finite Field of size 5 defined by X^2 + Y^2 - 2*Z^2
|
|
49
|
+
"""
|
|
50
|
+
def __init__(self, A, f):
|
|
51
|
+
r"""
|
|
52
|
+
See ``Conic`` for full documentation.
|
|
53
|
+
|
|
54
|
+
TESTS::
|
|
55
|
+
|
|
56
|
+
sage: conic = Conic([GF(7)(1), 1, -1]); conic
|
|
57
|
+
Projective Conic Curve over Finite Field of size 7 defined by x^2 + y^2 - z^2
|
|
58
|
+
sage: conic._test_pickling()
|
|
59
|
+
"""
|
|
60
|
+
ProjectiveConic_field.__init__(self, A, f)
|
|
61
|
+
|
|
62
|
+
def count_points(self, n):
|
|
63
|
+
r"""
|
|
64
|
+
If the base field `B` of ``self`` is finite of order `q`,
|
|
65
|
+
then returns the number of points over `\GF{q}, ..., \GF{q^n}`.
|
|
66
|
+
|
|
67
|
+
EXAMPLES::
|
|
68
|
+
|
|
69
|
+
sage: P.<x,y,z> = GF(3)[]
|
|
70
|
+
sage: c = Curve(x^2+y^2+z^2); c
|
|
71
|
+
Projective Conic Curve over Finite Field of size 3 defined by x^2 + y^2 + z^2
|
|
72
|
+
sage: c.count_points(4)
|
|
73
|
+
[4, 10, 28, 82]
|
|
74
|
+
"""
|
|
75
|
+
F = self.base_ring()
|
|
76
|
+
q = F.cardinality()
|
|
77
|
+
return [q**i + 1 for i in range(1, n + 1)]
|
|
78
|
+
|
|
79
|
+
def has_rational_point(self, point=False, read_cache=True,
|
|
80
|
+
algorithm='default'):
|
|
81
|
+
r"""
|
|
82
|
+
Always returns ``True`` because ``self`` has a point defined over
|
|
83
|
+
its finite base field `B`.
|
|
84
|
+
|
|
85
|
+
If ``point`` is True, then returns a second output `S`, which is a
|
|
86
|
+
rational point if one exists.
|
|
87
|
+
|
|
88
|
+
Points are cached. If ``read_cache`` is True, then cached information
|
|
89
|
+
is used for the output if available. If no cached point is available
|
|
90
|
+
or ``read_cache`` is False, then random `y`-coordinates are tried
|
|
91
|
+
if ``self`` is smooth and a singular point is returned otherwise.
|
|
92
|
+
|
|
93
|
+
EXAMPLES::
|
|
94
|
+
|
|
95
|
+
sage: Conic(FiniteField(37), [1, 2, 3, 4, 5, 6]).has_rational_point()
|
|
96
|
+
True
|
|
97
|
+
|
|
98
|
+
sage: C = Conic(FiniteField(2), [1, 1, 1, 1, 1, 0]); C
|
|
99
|
+
Projective Conic Curve over Finite Field of size 2
|
|
100
|
+
defined by x^2 + x*y + y^2 + x*z + y*z
|
|
101
|
+
sage: C.has_rational_point(point = True) # output is random
|
|
102
|
+
(True, (0 : 0 : 1))
|
|
103
|
+
|
|
104
|
+
sage: p = next_prime(10^50)
|
|
105
|
+
sage: F = FiniteField(p)
|
|
106
|
+
sage: C = Conic(F, [1, 2, 3]); C
|
|
107
|
+
Projective Conic Curve over Finite Field
|
|
108
|
+
of size 100000000000000000000000000000000000000000000000151
|
|
109
|
+
defined by x^2 + 2*y^2 + 3*z^2
|
|
110
|
+
sage: C.has_rational_point(point = True) # output is random
|
|
111
|
+
(True,
|
|
112
|
+
(14971942941468509742682168602989039212496867586852
|
|
113
|
+
: 75235465708017792892762202088174741054630437326388 : 1)
|
|
114
|
+
|
|
115
|
+
sage: F.<a> = FiniteField(7^20)
|
|
116
|
+
sage: C = Conic([1, a, -5]); C
|
|
117
|
+
Projective Conic Curve over Finite Field in a of size 7^20
|
|
118
|
+
defined by x^2 + a*y^2 + 2*z^2
|
|
119
|
+
sage: C.has_rational_point(point = True) # output is random
|
|
120
|
+
(True,
|
|
121
|
+
(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
|
|
122
|
+
+ 4*a^7 + a^6 + 4*a^4 + 6*a^2 + 3*a + 6
|
|
123
|
+
: 5*a^19 + 5*a^18 + 5*a^17 + a^16 + 2*a^15 + 3*a^14 + 4*a^13 + 5*a^12
|
|
124
|
+
+ 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
|
|
125
|
+
: 1))
|
|
126
|
+
|
|
127
|
+
TESTS::
|
|
128
|
+
|
|
129
|
+
sage: l = Sequence(cartesian_product_iterator([[0, 1] for i in range(6)]))
|
|
130
|
+
sage: bigF = GF(next_prime(2^100))
|
|
131
|
+
sage: bigF2 = GF(next_prime(2^50)^2, 'b')
|
|
132
|
+
sage: m = [[F(b) for b in a]
|
|
133
|
+
....: for a in l
|
|
134
|
+
....: for F in [GF(2), GF(4, 'a'), GF(5), GF(9, 'a'), bigF, bigF2]]
|
|
135
|
+
sage: m += [[F.random_element() for i in range(6)]
|
|
136
|
+
....: for j in range(20) for F in [GF(5), bigF]]
|
|
137
|
+
sage: c = [Conic(a) for a in m if a != [0,0,0,0,0,0]]
|
|
138
|
+
sage: assert all(C.has_rational_point() for C in c)
|
|
139
|
+
sage: r = randrange(0, 5)
|
|
140
|
+
sage: assert all(C.defining_polynomial()( # long time (1.4s on sage.math, 2013)
|
|
141
|
+
....: Sequence(C.has_rational_point(point=True)[1])) == 0
|
|
142
|
+
....: for C in c[r::5])
|
|
143
|
+
"""
|
|
144
|
+
if not point:
|
|
145
|
+
return True
|
|
146
|
+
if read_cache:
|
|
147
|
+
if self._rational_point is not None:
|
|
148
|
+
return True, self._rational_point
|
|
149
|
+
B = self.base_ring()
|
|
150
|
+
s, pt = self.has_singular_point(point=True)
|
|
151
|
+
if s:
|
|
152
|
+
return True, pt
|
|
153
|
+
while True:
|
|
154
|
+
x = B.random_element()
|
|
155
|
+
Y = PolynomialRing(B, 'Y').gen()
|
|
156
|
+
r = self.defining_polynomial()([x, Y, 1]).roots()
|
|
157
|
+
if r:
|
|
158
|
+
return True, self.point([x, r[0][0], B(1)])
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.rings.number_field
|
|
3
|
+
r"""
|
|
4
|
+
Projective plane conics over a number field
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Marco Streng (2010-07-20)
|
|
9
|
+
"""
|
|
10
|
+
# ****************************************************************************
|
|
11
|
+
# Copyright (C) 2009/2010 Marco Streng <marco.streng@gmail.com>
|
|
12
|
+
#
|
|
13
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
14
|
+
#
|
|
15
|
+
# This code is distributed in the hope that it will be useful,
|
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
18
|
+
# General Public License for more details.
|
|
19
|
+
#
|
|
20
|
+
# The full text of the GPL is available at:
|
|
21
|
+
#
|
|
22
|
+
# https://www.gnu.org/licenses/
|
|
23
|
+
# ****************************************************************************
|
|
24
|
+
|
|
25
|
+
from sage.rings.rational_field import RationalField
|
|
26
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
27
|
+
from .con_field import ProjectiveConic_field
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ProjectiveConic_number_field(ProjectiveConic_field):
|
|
31
|
+
r"""
|
|
32
|
+
Create a projective plane conic curve over a number field.
|
|
33
|
+
See ``Conic`` for full documentation.
|
|
34
|
+
|
|
35
|
+
EXAMPLES::
|
|
36
|
+
|
|
37
|
+
sage: x = polygen(QQ, 'x')
|
|
38
|
+
sage: K.<a> = NumberField(x^3 - 2, 'a')
|
|
39
|
+
sage: P.<X, Y, Z> = K[]
|
|
40
|
+
sage: Conic(X^2 + Y^2 - a*Z^2)
|
|
41
|
+
Projective Conic Curve over Number Field in a with defining polynomial x^3 - 2
|
|
42
|
+
defined by X^2 + Y^2 + (-a)*Z^2
|
|
43
|
+
|
|
44
|
+
TESTS::
|
|
45
|
+
|
|
46
|
+
sage: K.<a> = NumberField(x^3 - 3, 'a')
|
|
47
|
+
sage: Conic([a, 1, -1])._test_pickling()
|
|
48
|
+
"""
|
|
49
|
+
def __init__(self, A, f):
|
|
50
|
+
r"""
|
|
51
|
+
See ``Conic`` for full documentation.
|
|
52
|
+
|
|
53
|
+
EXAMPLES::
|
|
54
|
+
|
|
55
|
+
sage: Conic([1, 1, 1])
|
|
56
|
+
Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
|
|
57
|
+
"""
|
|
58
|
+
ProjectiveConic_field.__init__(self, A, f)
|
|
59
|
+
|
|
60
|
+
# a single prime such that self has no point over the completion
|
|
61
|
+
self._local_obstruction = None
|
|
62
|
+
# all finite primes such that self has no point over the completion
|
|
63
|
+
self._finite_obstructions = None
|
|
64
|
+
# all infinite primes such that self has no point over the completion
|
|
65
|
+
self._infinite_obstructions = None
|
|
66
|
+
|
|
67
|
+
def has_rational_point(self, point=False, obstruction=False,
|
|
68
|
+
algorithm='default', read_cache=True):
|
|
69
|
+
r"""
|
|
70
|
+
Return ``True`` if and only if ``self`` has a point
|
|
71
|
+
defined over its base field `B`.
|
|
72
|
+
|
|
73
|
+
If ``point`` and ``obstruction`` are both False (default),
|
|
74
|
+
then the output is a boolean ``out`` saying whether ``self``
|
|
75
|
+
has a rational point.
|
|
76
|
+
|
|
77
|
+
If ``point`` or ``obstruction`` is ``True``, then the output is
|
|
78
|
+
a pair ``(out, S)``, where ``out`` is as above and:
|
|
79
|
+
|
|
80
|
+
- if ``point`` is ``True`` and ``self`` has a rational point,
|
|
81
|
+
then ``S`` is a rational point,
|
|
82
|
+
|
|
83
|
+
- if ``obstruction`` is ``True``, ``self`` has no rational point,
|
|
84
|
+
then ``S`` is a prime or infinite place of `B` such that no
|
|
85
|
+
rational point exists over the completion at ``S``.
|
|
86
|
+
|
|
87
|
+
Points and obstructions are cached whenever they are found.
|
|
88
|
+
Cached information is used for the output if available, but only
|
|
89
|
+
if ``read_cache`` is ``True``.
|
|
90
|
+
|
|
91
|
+
ALGORITHM:
|
|
92
|
+
|
|
93
|
+
The parameter ``algorithm``
|
|
94
|
+
specifies the algorithm to be used:
|
|
95
|
+
|
|
96
|
+
- ``'rnfisnorm'`` -- use PARI's ``rnfisnorm``
|
|
97
|
+
(cannot be combined with ``obstruction = True``)
|
|
98
|
+
|
|
99
|
+
- ``'local'`` -- check if a local solution exists for all primes
|
|
100
|
+
and infinite places of `B` and apply the Hasse principle
|
|
101
|
+
(cannot be combined with ``point = True``)
|
|
102
|
+
|
|
103
|
+
- ``'default'`` -- use algorithm ``'rnfisnorm'`` first.
|
|
104
|
+
Then, if no point exists and obstructions are requested, use
|
|
105
|
+
algorithm ``'local'`` to find an obstruction.
|
|
106
|
+
|
|
107
|
+
- ``'magma'`` (requires Magma to be installed) --
|
|
108
|
+
delegates the task to the Magma computer algebra
|
|
109
|
+
system
|
|
110
|
+
|
|
111
|
+
EXAMPLES:
|
|
112
|
+
|
|
113
|
+
An example over `\QQ` ::
|
|
114
|
+
|
|
115
|
+
sage: C = Conic(QQ, [1, 113922743, -310146482690273725409])
|
|
116
|
+
sage: C.has_rational_point(point=True)
|
|
117
|
+
(True, (-76842858034579/5424 : -5316144401/5424 : 1))
|
|
118
|
+
sage: C.has_rational_point(algorithm='local', read_cache=False)
|
|
119
|
+
True
|
|
120
|
+
|
|
121
|
+
Examples over number fields::
|
|
122
|
+
|
|
123
|
+
sage: K.<i> = QuadraticField(-1)
|
|
124
|
+
sage: C = Conic(K, [1, 3, -5])
|
|
125
|
+
sage: C.has_rational_point(point=True, obstruction=True)
|
|
126
|
+
(False, Fractional ideal (2*i - 1))
|
|
127
|
+
sage: C.has_rational_point(algorithm='rnfisnorm')
|
|
128
|
+
False
|
|
129
|
+
sage: C.has_rational_point(algorithm='rnfisnorm', obstruction=True,
|
|
130
|
+
....: read_cache=False)
|
|
131
|
+
Traceback (most recent call last):
|
|
132
|
+
...
|
|
133
|
+
ValueError: Algorithm rnfisnorm cannot be combined with
|
|
134
|
+
obstruction = True in has_rational_point
|
|
135
|
+
|
|
136
|
+
sage: P.<x> = QQ[]
|
|
137
|
+
sage: L.<b> = NumberField(x^3 - 5)
|
|
138
|
+
sage: C = Conic(L, [1, 2, -3])
|
|
139
|
+
sage: C.has_rational_point(point=True, algorithm='rnfisnorm')
|
|
140
|
+
(True, (-5/3 : 1/3 : 1))
|
|
141
|
+
|
|
142
|
+
sage: K.<a> = NumberField(x^4+2)
|
|
143
|
+
sage: Conic(QQ, [4,5,6]).has_rational_point()
|
|
144
|
+
False
|
|
145
|
+
sage: Conic(K, [4,5,6]).has_rational_point()
|
|
146
|
+
True
|
|
147
|
+
sage: Conic(K, [4,5,6]).has_rational_point(algorithm='magma', # optional - magma
|
|
148
|
+
....: read_cache=False)
|
|
149
|
+
True
|
|
150
|
+
|
|
151
|
+
sage: P.<a> = QuadraticField(2)
|
|
152
|
+
sage: C = Conic(P, [1,1,1])
|
|
153
|
+
sage: C.has_rational_point()
|
|
154
|
+
False
|
|
155
|
+
sage: C.has_rational_point(point=True)
|
|
156
|
+
(False, None)
|
|
157
|
+
sage: C.has_rational_point(obstruction=True)
|
|
158
|
+
(False,
|
|
159
|
+
Ring morphism:
|
|
160
|
+
From: Number Field in a with defining polynomial x^2 - 2
|
|
161
|
+
with a = 1.414213562373095?
|
|
162
|
+
To: Algebraic Real Field
|
|
163
|
+
Defn: a |--> -1.414213562373095?)
|
|
164
|
+
sage: C.has_rational_point(point=True, obstruction=True)
|
|
165
|
+
(False,
|
|
166
|
+
Ring morphism:
|
|
167
|
+
From: Number Field in a with defining polynomial x^2 - 2
|
|
168
|
+
with a = 1.414213562373095?
|
|
169
|
+
To: Algebraic Real Field
|
|
170
|
+
Defn: a |--> -1.414213562373095?)
|
|
171
|
+
|
|
172
|
+
TESTS:
|
|
173
|
+
|
|
174
|
+
Create a bunch of conics over number fields and check whether
|
|
175
|
+
``has_rational_point`` runs without errors for algorithms
|
|
176
|
+
``'rnfisnorm'`` and ``'local'``. Check if all points returned are
|
|
177
|
+
valid. If Magma is available, then also check if the output agrees with
|
|
178
|
+
Magma. ::
|
|
179
|
+
|
|
180
|
+
sage: P.<X> = QQ[]
|
|
181
|
+
sage: Q = P.fraction_field()
|
|
182
|
+
sage: c = [1, X/2, 1/X]
|
|
183
|
+
sage: l = Sequence(cartesian_product_iterator([c for i in range(3)]))
|
|
184
|
+
sage: l = l + [[X, 1, 1, 1, 1, 1]] + [[X, 1/5, 1, 1, 2, 1]]
|
|
185
|
+
sage: K.<a> = QuadraticField(-23)
|
|
186
|
+
sage: L.<b> = QuadraticField(19)
|
|
187
|
+
sage: M.<c> = NumberField(X^3+3*X+1)
|
|
188
|
+
sage: m = [[Q(b)(F.gen()) for b in a] for a in l for F in [K, L, M]]
|
|
189
|
+
sage: d = []
|
|
190
|
+
sage: c = []
|
|
191
|
+
sage: c = [Conic(a) for a in m if a != [0,0,0]]
|
|
192
|
+
sage: d = [C.has_rational_point(algorithm='rnfisnorm', point=True) for C in c] # long time: 3.3 seconds
|
|
193
|
+
sage: all(c[k].defining_polynomial()(Sequence(d[k][1])) == 0 for k in range(len(d)) if d[k][0])
|
|
194
|
+
True
|
|
195
|
+
sage: [C.has_rational_point(algorithm='local', read_cache=False) for C in c] == [o[0] for o in d] # long time: 5 seconds
|
|
196
|
+
True
|
|
197
|
+
sage: [C.has_rational_point(algorithm='magma', read_cache=False) for C in c] == [o[0] for o in d] # long time: 3 seconds, optional - magma
|
|
198
|
+
True
|
|
199
|
+
|
|
200
|
+
Create a bunch of conics that are known to have rational points
|
|
201
|
+
already over `\QQ` and check if points are found by
|
|
202
|
+
``has_rational_point``. ::
|
|
203
|
+
|
|
204
|
+
sage: l = Sequence(cartesian_product_iterator([[-1, 0, 1] for i in range(3)]))
|
|
205
|
+
sage: K.<a> = QuadraticField(-23)
|
|
206
|
+
sage: L.<b> = QuadraticField(19)
|
|
207
|
+
sage: M.<c> = NumberField(x^5+3*x+1)
|
|
208
|
+
sage: m = [[F(b) for b in a] for a in l for F in [K, L, M]]
|
|
209
|
+
sage: c = [Conic(a) for a in m if a != [0,0,0] and a != [1,1,1] and a != [-1,-1,-1]]
|
|
210
|
+
sage: assert all(C.has_rational_point(algorithm='rnfisnorm') for C in c)
|
|
211
|
+
sage: assert all(C.defining_polynomial()(Sequence(C.has_rational_point(point=True)[1])) == 0 for C in c)
|
|
212
|
+
sage: assert all(C.has_rational_point(algorithm='local', read_cache=False) for C in c) # long time: 1 second
|
|
213
|
+
"""
|
|
214
|
+
if read_cache:
|
|
215
|
+
if self._rational_point is not None:
|
|
216
|
+
# a rational point is already known, return True
|
|
217
|
+
if point or obstruction:
|
|
218
|
+
return True, self._rational_point
|
|
219
|
+
else:
|
|
220
|
+
return True
|
|
221
|
+
if self._local_obstruction is not None:
|
|
222
|
+
# a local obstruction is already known, return False
|
|
223
|
+
if point or obstruction:
|
|
224
|
+
return False, self._local_obstruction
|
|
225
|
+
else:
|
|
226
|
+
return False
|
|
227
|
+
# `_(in)finite_obstructions` is ``None`` if the cache is empty,
|
|
228
|
+
# so we explicitly check against a list:
|
|
229
|
+
if (not point) and self._finite_obstructions == [] and \
|
|
230
|
+
self._infinite_obstructions == []:
|
|
231
|
+
# list of local obstructions is computed and empty, return True
|
|
232
|
+
if obstruction:
|
|
233
|
+
return True, None
|
|
234
|
+
return True
|
|
235
|
+
|
|
236
|
+
# cache is empty or user specifically asks not to check the cache
|
|
237
|
+
|
|
238
|
+
if self.has_singular_point():
|
|
239
|
+
if point:
|
|
240
|
+
return self.has_singular_point(point=True)
|
|
241
|
+
if obstruction:
|
|
242
|
+
return True, None
|
|
243
|
+
return True
|
|
244
|
+
B = self.base_ring()
|
|
245
|
+
|
|
246
|
+
if algorithm == 'default':
|
|
247
|
+
ret = self.has_rational_point(point=True, obstruction=False,
|
|
248
|
+
algorithm='rnfisnorm',
|
|
249
|
+
read_cache=False)
|
|
250
|
+
if ret[0]:
|
|
251
|
+
if point or obstruction:
|
|
252
|
+
return ret
|
|
253
|
+
return True
|
|
254
|
+
if obstruction:
|
|
255
|
+
ret = self.has_rational_point(point=False, obstruction=True,
|
|
256
|
+
algorithm='local',
|
|
257
|
+
read_cache=False)
|
|
258
|
+
if ret[0]:
|
|
259
|
+
raise RuntimeError("Outputs of algorithms in "
|
|
260
|
+
"has_rational_point disagree "
|
|
261
|
+
"for conic %s" % self)
|
|
262
|
+
return ret
|
|
263
|
+
if point:
|
|
264
|
+
return False, None
|
|
265
|
+
return False
|
|
266
|
+
|
|
267
|
+
if algorithm == 'local':
|
|
268
|
+
if point:
|
|
269
|
+
raise ValueError("Algorithm 'local' cannot be combined "
|
|
270
|
+
"with point = True in has_rational_point")
|
|
271
|
+
obs = self.local_obstructions(infinite=True, finite=False,
|
|
272
|
+
read_cache=read_cache)
|
|
273
|
+
if obs:
|
|
274
|
+
if obstruction:
|
|
275
|
+
return False, obs[0]
|
|
276
|
+
return False
|
|
277
|
+
obs = self.local_obstructions(read_cache=read_cache)
|
|
278
|
+
if not obs:
|
|
279
|
+
if obstruction:
|
|
280
|
+
return True, None
|
|
281
|
+
return True
|
|
282
|
+
if obstruction:
|
|
283
|
+
return False, obs[0]
|
|
284
|
+
return False
|
|
285
|
+
if algorithm == 'rnfisnorm':
|
|
286
|
+
from sage.modules.free_module_element import vector
|
|
287
|
+
if obstruction:
|
|
288
|
+
raise ValueError("Algorithm rnfisnorm cannot be combined "
|
|
289
|
+
"with obstruction = True in "
|
|
290
|
+
"has_rational_point")
|
|
291
|
+
D, T = self.diagonal_matrix()
|
|
292
|
+
abc = [D[0, 0], D[1, 1], D[2, 2]]
|
|
293
|
+
for j in range(3):
|
|
294
|
+
if abc[j] == 0:
|
|
295
|
+
pt = self.point(T * vector({2: 0, j: 1}))
|
|
296
|
+
if point or obstruction:
|
|
297
|
+
return True, pt
|
|
298
|
+
return True
|
|
299
|
+
if (-abc[1] / abc[0]).is_square():
|
|
300
|
+
pt = self.point(T * vector([(-abc[1] / abc[0]).sqrt(), 1, 0]))
|
|
301
|
+
if point or obstruction:
|
|
302
|
+
return True, pt
|
|
303
|
+
return True
|
|
304
|
+
if (-abc[2] / abc[0]).is_square():
|
|
305
|
+
pt = self.point(T * vector([(-abc[2] / abc[0]).sqrt(), 0, 1]))
|
|
306
|
+
if point or obstruction:
|
|
307
|
+
return True, pt
|
|
308
|
+
return True
|
|
309
|
+
if isinstance(B, RationalField):
|
|
310
|
+
K = B
|
|
311
|
+
[KtoB, BtoK] = [K.hom(K) for i in range(2)]
|
|
312
|
+
else:
|
|
313
|
+
K = B.absolute_field('Y')
|
|
314
|
+
[KtoB, BtoK] = K.structure()
|
|
315
|
+
X = PolynomialRing(K, 'X').gen()
|
|
316
|
+
d = BtoK(-abc[1] / abc[0])
|
|
317
|
+
den = d.denominator()
|
|
318
|
+
L = K.extension(X**2 - d * den**2, names='y')
|
|
319
|
+
isnorm = BtoK(-abc[2] / abc[0]).is_norm(L, element=True)
|
|
320
|
+
if isnorm[0]:
|
|
321
|
+
|
|
322
|
+
pt = self.point(T * vector([KtoB(isnorm[1][0]),
|
|
323
|
+
KtoB(isnorm[1][1] * den), 1]))
|
|
324
|
+
if point:
|
|
325
|
+
return True, pt
|
|
326
|
+
return True
|
|
327
|
+
if point:
|
|
328
|
+
return False, None
|
|
329
|
+
return False
|
|
330
|
+
if algorithm == 'qfsolve':
|
|
331
|
+
raise TypeError("Algorithm qfsolve in has_rational_point only "
|
|
332
|
+
"for conics over QQ, not over %s" % B)
|
|
333
|
+
if obstruction:
|
|
334
|
+
raise ValueError("Invalid combination: obstruction=True and "
|
|
335
|
+
"algorithm=%s" % algorithm)
|
|
336
|
+
|
|
337
|
+
return ProjectiveConic_field.has_rational_point(self, point=point,
|
|
338
|
+
algorithm=algorithm, read_cache=False)
|
|
339
|
+
|
|
340
|
+
def is_locally_solvable(self, p):
|
|
341
|
+
r"""
|
|
342
|
+
Return ``True`` if and only if ``self`` has a solution over the
|
|
343
|
+
completion of the base field `B` of ``self`` at ``p``. Here ``p``
|
|
344
|
+
is a finite prime or infinite place of `B`.
|
|
345
|
+
|
|
346
|
+
EXAMPLES::
|
|
347
|
+
|
|
348
|
+
sage: P.<x> = QQ[]
|
|
349
|
+
sage: K.<a> = NumberField(x^3 + 5)
|
|
350
|
+
sage: C = Conic(K, [1, 2, 3 - a])
|
|
351
|
+
sage: [p1, p2] = K.places()
|
|
352
|
+
sage: C.is_locally_solvable(p1)
|
|
353
|
+
False
|
|
354
|
+
|
|
355
|
+
sage: C.is_locally_solvable(p2)
|
|
356
|
+
True
|
|
357
|
+
|
|
358
|
+
sage: f = (2*K).factor()
|
|
359
|
+
sage: C.is_locally_solvable(f[0][0])
|
|
360
|
+
True
|
|
361
|
+
|
|
362
|
+
sage: C.is_locally_solvable(f[1][0])
|
|
363
|
+
False
|
|
364
|
+
"""
|
|
365
|
+
D, T = self.diagonal_matrix()
|
|
366
|
+
abc = [D[j, j] for j in range(3)]
|
|
367
|
+
for a in abc:
|
|
368
|
+
if a == 0:
|
|
369
|
+
return True
|
|
370
|
+
a = -abc[0] / abc[2]
|
|
371
|
+
b = -abc[1] / abc[2]
|
|
372
|
+
|
|
373
|
+
ret = self.base_ring().hilbert_symbol(a, b, p)
|
|
374
|
+
|
|
375
|
+
if ret == -1:
|
|
376
|
+
if self._local_obstruction is None:
|
|
377
|
+
from sage.categories.map import Map
|
|
378
|
+
from sage.categories.rings import Rings
|
|
379
|
+
from sage.rings.qqbar import AA
|
|
380
|
+
from sage.rings.real_lazy import RLF
|
|
381
|
+
|
|
382
|
+
if not (isinstance(p, Map) and p.category_for().is_subcategory(Rings())) or p.codomain() is AA or p.codomain() is RLF:
|
|
383
|
+
self._local_obstruction = p
|
|
384
|
+
return False
|
|
385
|
+
|
|
386
|
+
return True
|
|
387
|
+
|
|
388
|
+
def local_obstructions(self, finite=True, infinite=True, read_cache=True):
|
|
389
|
+
r"""
|
|
390
|
+
Return the sequence of finite primes and/or infinite places
|
|
391
|
+
such that ``self`` is locally solvable at those primes and places.
|
|
392
|
+
|
|
393
|
+
If the base field is `\QQ`, then the infinite place is denoted `-1`.
|
|
394
|
+
|
|
395
|
+
The parameters ``finite`` and ``infinite`` (both ``True`` by default) are
|
|
396
|
+
used to specify whether to look at finite and/or infinite places.
|
|
397
|
+
Note that ``finite = True`` involves factorization of the determinant
|
|
398
|
+
of ``self``, hence may be slow.
|
|
399
|
+
|
|
400
|
+
Local obstructions are cached. The parameter ``read_cache``
|
|
401
|
+
specifies whether to look at the cache before computing anything.
|
|
402
|
+
|
|
403
|
+
EXAMPLES::
|
|
404
|
+
|
|
405
|
+
sage: K.<i> = QuadraticField(-1)
|
|
406
|
+
sage: Conic(K, [1, 2, 3]).local_obstructions()
|
|
407
|
+
[]
|
|
408
|
+
|
|
409
|
+
sage: L.<a> = QuadraticField(5)
|
|
410
|
+
sage: Conic(L, [1, 2, 3]).local_obstructions()
|
|
411
|
+
[Ring morphism:
|
|
412
|
+
From: Number Field in a with defining polynomial x^2 - 5
|
|
413
|
+
with a = 2.236067977499790?
|
|
414
|
+
To: Algebraic Real Field
|
|
415
|
+
Defn: a |--> -2.236067977499790?,
|
|
416
|
+
Ring morphism:
|
|
417
|
+
From: Number Field in a with defining polynomial x^2 - 5
|
|
418
|
+
with a = 2.236067977499790?
|
|
419
|
+
To: Algebraic Real Field
|
|
420
|
+
Defn: a |--> 2.236067977499790?]
|
|
421
|
+
"""
|
|
422
|
+
obs0 = []
|
|
423
|
+
obs1 = []
|
|
424
|
+
B = self.base_ring()
|
|
425
|
+
if infinite:
|
|
426
|
+
if read_cache and self._infinite_obstructions is not None:
|
|
427
|
+
obs0 = self._infinite_obstructions
|
|
428
|
+
else:
|
|
429
|
+
from sage.rings.qqbar import AA
|
|
430
|
+
for b in B.embeddings(AA):
|
|
431
|
+
if not self.is_locally_solvable(b):
|
|
432
|
+
obs0.append(b)
|
|
433
|
+
self._infinite_obstructions = obs0
|
|
434
|
+
if finite:
|
|
435
|
+
if read_cache and self._finite_obstructions is not None:
|
|
436
|
+
obs1 = self._finite_obstructions
|
|
437
|
+
else:
|
|
438
|
+
candidates = []
|
|
439
|
+
if self.determinant() != 0:
|
|
440
|
+
O = B.maximal_order()
|
|
441
|
+
for a in self.symmetric_matrix().list():
|
|
442
|
+
if a != 0:
|
|
443
|
+
for f in O.fractional_ideal(a).factor():
|
|
444
|
+
if f[1] < 0 and f[0] not in candidates:
|
|
445
|
+
candidates.append(f[0])
|
|
446
|
+
for f in O.fractional_ideal(2 * self.determinant()).factor():
|
|
447
|
+
if f[1] > 0 and f[0] not in candidates:
|
|
448
|
+
candidates.append(f[0])
|
|
449
|
+
for b in candidates:
|
|
450
|
+
if not self.is_locally_solvable(b):
|
|
451
|
+
obs1.append(b)
|
|
452
|
+
self._infinite_obstructions = obs1
|
|
453
|
+
obs = obs1 + obs0
|
|
454
|
+
if finite and infinite:
|
|
455
|
+
assert len(obs) % 2 == 0
|
|
456
|
+
return obs
|