passagemath-schemes 10.6.38__cp314-cp314t-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.21.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.38.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.38.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.38.dist-info/RECORD +314 -0
- passagemath_schemes-10.6.38.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.38.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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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,580 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
r"""
|
|
3
|
+
Projective plane conics over a rational function field
|
|
4
|
+
|
|
5
|
+
The class :class:`ProjectiveConic_rational_function_field` represents a
|
|
6
|
+
projective plane conic over a rational function field `F(t)`, where `F`
|
|
7
|
+
is any field. Instances can be created using :func:`Conic`.
|
|
8
|
+
|
|
9
|
+
AUTHORS:
|
|
10
|
+
|
|
11
|
+
- Lennart Ackermans (2016-02-07): initial version
|
|
12
|
+
|
|
13
|
+
EXAMPLES:
|
|
14
|
+
|
|
15
|
+
Create a conic::
|
|
16
|
+
|
|
17
|
+
sage: K = FractionField(PolynomialRing(QQ, 't'))
|
|
18
|
+
sage: P.<X, Y, Z> = K[]
|
|
19
|
+
sage: Conic(X^2 + Y^2 - Z^2)
|
|
20
|
+
Projective Conic Curve over Fraction Field of Univariate
|
|
21
|
+
Polynomial Ring in t over Rational Field defined by
|
|
22
|
+
X^2 + Y^2 - Z^2
|
|
23
|
+
|
|
24
|
+
Points can be found using :meth:`has_rational_point`::
|
|
25
|
+
|
|
26
|
+
sage: K.<t> = FractionField(QQ['t'])
|
|
27
|
+
sage: C = Conic([1, -t, t])
|
|
28
|
+
sage: C.has_rational_point(point=True) # needs sage.libs.singular
|
|
29
|
+
(True, (0 : 1 : 1))
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
# ****************************************************************************
|
|
33
|
+
# Copyright (C) 2016 Lennart Ackermans
|
|
34
|
+
#
|
|
35
|
+
# This program is free software: you can redistribute it and/or modify
|
|
36
|
+
# it under the terms of the GNU General Public License as published by
|
|
37
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
38
|
+
# (at your option) any later version.
|
|
39
|
+
# https://www.gnu.org/licenses/
|
|
40
|
+
# ****************************************************************************
|
|
41
|
+
|
|
42
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
43
|
+
from sage.matrix.constructor import diagonal_matrix, matrix, block_matrix
|
|
44
|
+
from sage.schemes.plane_conics.con_field import ProjectiveConic_field
|
|
45
|
+
from sage.arith.functions import lcm
|
|
46
|
+
from sage.arith.misc import GCD as gcd
|
|
47
|
+
from sage.modules.free_module_element import vector
|
|
48
|
+
from sage.rings.fraction_field import FractionField_generic
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ProjectiveConic_rational_function_field(ProjectiveConic_field):
|
|
52
|
+
r"""
|
|
53
|
+
Create a projective plane conic curve over a rational function field
|
|
54
|
+
`F(t)`, where `F` is any field.
|
|
55
|
+
|
|
56
|
+
The algorithms used in this class come mostly from [HC2006]_.
|
|
57
|
+
|
|
58
|
+
EXAMPLES::
|
|
59
|
+
|
|
60
|
+
sage: K = FractionField(PolynomialRing(QQ, 't'))
|
|
61
|
+
sage: P.<X, Y, Z> = K[]
|
|
62
|
+
sage: Conic(X^2 + Y^2 - Z^2)
|
|
63
|
+
Projective Conic Curve over Fraction Field of Univariate
|
|
64
|
+
Polynomial Ring in t over Rational Field defined by
|
|
65
|
+
X^2 + Y^2 - Z^2
|
|
66
|
+
|
|
67
|
+
TESTS::
|
|
68
|
+
|
|
69
|
+
sage: K = FractionField(PolynomialRing(QQ, 't'))
|
|
70
|
+
sage: Conic([K(1), 1, -1])._test_pickling()
|
|
71
|
+
|
|
72
|
+
REFERENCES:
|
|
73
|
+
|
|
74
|
+
- [HC2006]_
|
|
75
|
+
- [Ack2016]_
|
|
76
|
+
"""
|
|
77
|
+
def __init__(self, A, f):
|
|
78
|
+
r"""
|
|
79
|
+
See ``Conic`` for full documentation.
|
|
80
|
+
|
|
81
|
+
EXAMPLES::
|
|
82
|
+
|
|
83
|
+
sage: c = Conic([1, 1, 1]); c
|
|
84
|
+
Projective Conic Curve over Rational Field defined by
|
|
85
|
+
x^2 + y^2 + z^2
|
|
86
|
+
"""
|
|
87
|
+
ProjectiveConic_field.__init__(self, A, f)
|
|
88
|
+
|
|
89
|
+
def has_rational_point(self, point=False, algorithm='default',
|
|
90
|
+
read_cache=True):
|
|
91
|
+
r"""
|
|
92
|
+
Return ``True`` if and only if the conic ``self``
|
|
93
|
+
has a point over its base field `F(t)`, which is a field of rational
|
|
94
|
+
functions.
|
|
95
|
+
|
|
96
|
+
If ``point`` is True, then returns a second output, which is
|
|
97
|
+
a rational point if one exists.
|
|
98
|
+
|
|
99
|
+
Points are cached whenever they are found. Cached information
|
|
100
|
+
is used if and only if ``read_cache`` is True.
|
|
101
|
+
|
|
102
|
+
The default algorithm does not (yet) work for all base fields `F`.
|
|
103
|
+
In particular, sage is required to have:
|
|
104
|
+
|
|
105
|
+
* an algorithm for finding the square root of elements in finite
|
|
106
|
+
extensions of `F`;
|
|
107
|
+
|
|
108
|
+
* a factorization and gcd algorithm for `F[t]`;
|
|
109
|
+
|
|
110
|
+
* an algorithm for solving conics over `F`.
|
|
111
|
+
|
|
112
|
+
ALGORITHM:
|
|
113
|
+
|
|
114
|
+
The parameter ``algorithm`` specifies the algorithm
|
|
115
|
+
to be used:
|
|
116
|
+
|
|
117
|
+
* ``'default'`` -- use a native Sage implementation, based on the
|
|
118
|
+
algorithm Conic in [HC2006]_.
|
|
119
|
+
|
|
120
|
+
* ``'magma'`` (requires Magma to be installed) --
|
|
121
|
+
delegates the task to the Magma computer algebra
|
|
122
|
+
system.
|
|
123
|
+
|
|
124
|
+
EXAMPLES:
|
|
125
|
+
|
|
126
|
+
We can find points for function fields over (extensions of) `\QQ`
|
|
127
|
+
and finite fields::
|
|
128
|
+
|
|
129
|
+
sage: K.<t> = FractionField(PolynomialRing(QQ, 't'))
|
|
130
|
+
sage: C = Conic(K, [t^2 - 2, 2*t^3, -2*t^3 - 13*t^2 - 2*t + 18])
|
|
131
|
+
sage: C.has_rational_point(point=True) # needs sage.libs.singular
|
|
132
|
+
(True, (-3 : (t + 1)/t : 1))
|
|
133
|
+
|
|
134
|
+
sage: R.<t> = FiniteField(23)[]
|
|
135
|
+
sage: C = Conic([2, t^2 + 1, t^2 + 5])
|
|
136
|
+
sage: C.has_rational_point() # needs sage.libs.singular
|
|
137
|
+
True
|
|
138
|
+
sage: C.has_rational_point(point=True) # needs sage.libs.singular
|
|
139
|
+
(True, (5*t : 8 : 1))
|
|
140
|
+
|
|
141
|
+
sage: # needs sage.rings.number_field
|
|
142
|
+
sage: F.<i> = QuadraticField(-1)
|
|
143
|
+
sage: R.<t> = F[]
|
|
144
|
+
sage: C = Conic([1, i*t, -t^2 + 4])
|
|
145
|
+
sage: C.has_rational_point(point=True) # needs sage.libs.singular
|
|
146
|
+
(True, (-t - 2*i : -2*i : 1))
|
|
147
|
+
|
|
148
|
+
It works on non-diagonal conics as well::
|
|
149
|
+
|
|
150
|
+
sage: K.<t> = QQ[]
|
|
151
|
+
sage: C = Conic([4, -4, 8, 1, -4, t + 4])
|
|
152
|
+
sage: C.has_rational_point(point=True) # needs sage.libs.singular
|
|
153
|
+
(True, (1/2 : 1 : 0))
|
|
154
|
+
|
|
155
|
+
If no point exists output still depends on the argument ``point``::
|
|
156
|
+
|
|
157
|
+
sage: K.<t> = QQ[]
|
|
158
|
+
sage: C = Conic(K, [t^2, (t-1), -2*(t-1)])
|
|
159
|
+
sage: C.has_rational_point() # needs sage.libs.singular
|
|
160
|
+
False
|
|
161
|
+
sage: C.has_rational_point(point=True) # needs sage.libs.singular
|
|
162
|
+
(False, None)
|
|
163
|
+
|
|
164
|
+
Due to limitations in Sage of algorithms we depend on, it is not
|
|
165
|
+
yet possible to find points on conics over multivariate function fields
|
|
166
|
+
(see the requirements above)::
|
|
167
|
+
|
|
168
|
+
sage: F.<t1> = FractionField(QQ['t1'])
|
|
169
|
+
sage: K.<t2> = FractionField(F['t2'])
|
|
170
|
+
sage: a = K(1)
|
|
171
|
+
sage: b = 2*t2^2 + 2*t1*t2 - t1^2
|
|
172
|
+
sage: c = -3*t2^4 - 4*t1*t2^3 + 8*t1^2*t2^2 + 16*t1^3 - t2 - 48*t1^4
|
|
173
|
+
sage: C = Conic([a,b,c])
|
|
174
|
+
sage: C.has_rational_point() # needs sage.libs.singular
|
|
175
|
+
Traceback (most recent call last):
|
|
176
|
+
...
|
|
177
|
+
NotImplementedError: is_square() not implemented for elements of
|
|
178
|
+
Univariate Quotient Polynomial Ring in tbar over Fraction Field
|
|
179
|
+
of Univariate Polynomial Ring in t1 over Rational Field with
|
|
180
|
+
modulus tbar^2 + t1*tbar - 1/2*t1^2
|
|
181
|
+
|
|
182
|
+
In some cases, the algorithm requires us to be
|
|
183
|
+
able to solve conics over `F`. In particular, the following does not
|
|
184
|
+
work::
|
|
185
|
+
|
|
186
|
+
sage: P.<u> = QQ[]
|
|
187
|
+
sage: E = P.fraction_field()
|
|
188
|
+
sage: Q.<Y> = E[]
|
|
189
|
+
sage: F.<v> = E.extension(Y^2 - u^3 - 1)
|
|
190
|
+
sage: R.<t> = F[]
|
|
191
|
+
sage: K = R.fraction_field() # needs sage.rings.function_field
|
|
192
|
+
sage: C = Conic(K, [u, v, 1]) # needs sage.rings.function_field
|
|
193
|
+
sage: C.has_rational_point() # needs sage.rings.function_field
|
|
194
|
+
Traceback (most recent call last):
|
|
195
|
+
...
|
|
196
|
+
NotImplementedError: has_rational_point not implemented for conics
|
|
197
|
+
over base field Univariate Quotient Polynomial Ring in v over
|
|
198
|
+
Fraction Field of Univariate Polynomial Ring in u over Rational
|
|
199
|
+
Field with modulus v^2 - u^3 - 1
|
|
200
|
+
|
|
201
|
+
TESTS::
|
|
202
|
+
|
|
203
|
+
sage: K.<t> = FractionField(PolynomialRing(QQ, 't'))
|
|
204
|
+
sage: a = (2*t^2 - 3/2*t + 1)/(37/3*t^2 + t - 1/4)
|
|
205
|
+
sage: b = (1/2*t^2 + 1/3)/(-73*t^2 - 2*t + 11/4)
|
|
206
|
+
sage: c = (6934/3*t^6 + 8798/3*t^5 - 947/18*t^4 + 3949/9*t^3 + 20983/18*t^2 + 28/3*t - 131/3)/(-2701/3*t^4 - 293/3*t^3 + 301/6*t^2 + 13/4*t - 11/16)
|
|
207
|
+
sage: C = Conic([a,b,c])
|
|
208
|
+
sage: C.has_rational_point(point=True) # needs sage.libs.singular
|
|
209
|
+
(True, (4*t + 4 : 2*t + 2 : 1))
|
|
210
|
+
|
|
211
|
+
A long time test::
|
|
212
|
+
|
|
213
|
+
sage: K.<t> = FractionField(PolynomialRing(QQ, 't'))
|
|
214
|
+
sage: a = (-1/3*t^6 - 14*t^5 - 1/4*t^4 + 7/2*t^2 - 1/2*t - 1)/(24/5*t^6 - t^5 - 1/4*t^4 + t^3 - 3*t^2 + 8/5*t + 5)
|
|
215
|
+
sage: b = (-3*t^3 + 8*t + 1/2)/(-1/3*t^3 + 3/2*t^2 + 1/12*t + 1/2)
|
|
216
|
+
sage: c = (1232009/225*t^25 - 1015925057/8100*t^24 + 1035477411553/1458000*t^23 + 7901338091/30375*t^22 - 1421379260447/729000*t^21 + 266121260843/972000*t^20 + 80808723191/486000*t^19 - 516656082523/972000*t^18 + 21521589529/40500*t^17 + 4654758997/21600*t^16 - 20064038625227/9720000*t^15 - 173054270347/324000*t^14 + 536200870559/540000*t^13 - 12710739349/50625*t^12 - 197968226971/135000*t^11 - 134122025657/810000*t^10 + 22685316301/120000*t^9 - 2230847689/21600*t^8 - 70624099679/270000*t^7 - 4298763061/270000*t^6 - 41239/216000*t^5 - 13523/36000*t^4 + 493/36000*t^3 + 83/2400*t^2 + 1/300*t + 1/200)/(-27378/125*t^17 + 504387/500*t^16 - 97911/2000*t^15 + 1023531/4000*t^14 + 1874841/8000*t^13 + 865381/12000*t^12 + 15287/375*t^11 + 6039821/6000*t^10 + 599437/1500*t^9 + 18659/250*t^8 + 1218059/6000*t^7 + 2025127/3000*t^6 + 1222759/6000*t^5 + 38573/200*t^4 + 8323/125*t^3 + 15453/125*t^2 + 17031/500*t + 441/10)
|
|
217
|
+
sage: C = Conic([a,b,c])
|
|
218
|
+
sage: C.has_rational_point(point=True) # long time (4 seconds) # needs sage.libs.singular
|
|
219
|
+
(True,
|
|
220
|
+
((-2/117*t^8 + 304/1053*t^7 + 40/117*t^6 - 1/27*t^5 - 110/351*t^4 - 2/195*t^3 + 11/351*t^2 + 1/117)/(t^4 + 2/39*t^3 + 4/117*t^2 + 2/39*t + 14/39) : -5/3*t^4 + 19*t^3 : 1))
|
|
221
|
+
|
|
222
|
+
``has_rational_point`` used to fail for some conics over function fields
|
|
223
|
+
over finite fields, due to :issue:`20003`::
|
|
224
|
+
|
|
225
|
+
sage: K.<t> = PolynomialRing(GF(7))
|
|
226
|
+
sage: C = Conic([5*t^2 + 4, t^2 + 3*t + 3, 6*t^2 + 3*t + 2,
|
|
227
|
+
....: 5*t^2 + 5, 4*t + 3, 4*t^2 + t + 5])
|
|
228
|
+
sage: C.has_rational_point()
|
|
229
|
+
True
|
|
230
|
+
"""
|
|
231
|
+
from .constructor import Conic
|
|
232
|
+
|
|
233
|
+
if read_cache:
|
|
234
|
+
if self._rational_point is not None:
|
|
235
|
+
return (True, self._rational_point) if point else True
|
|
236
|
+
|
|
237
|
+
if algorithm != 'default':
|
|
238
|
+
return ProjectiveConic_field.has_rational_point(self, point,
|
|
239
|
+
algorithm, read_cache)
|
|
240
|
+
|
|
241
|
+
# Default algorithm
|
|
242
|
+
if self.base_ring().characteristic() == 2:
|
|
243
|
+
raise NotImplementedError("has_rational_point not implemented \
|
|
244
|
+
for function field of characteristic 2.")
|
|
245
|
+
new_conic, transformation, inverse = self.diagonalization()
|
|
246
|
+
coeff = new_conic.coefficients()
|
|
247
|
+
if coeff[0] == 0:
|
|
248
|
+
return (True, transformation([1, 0, 0])) if point else True
|
|
249
|
+
elif coeff[3] == 0:
|
|
250
|
+
return (True, transformation([0, 1, 0])) if point else True
|
|
251
|
+
elif coeff[5] == 0:
|
|
252
|
+
return (True, transformation([0, 0, 1])) if point else True
|
|
253
|
+
|
|
254
|
+
# We save the coefficients of the reduced form in coeff
|
|
255
|
+
# A zero of the reduced conic can be multiplied by multipliers
|
|
256
|
+
# to get a zero of the old conic
|
|
257
|
+
(coeff, multipliers) = new_conic._reduce_conic()
|
|
258
|
+
new_conic = Conic(coeff)
|
|
259
|
+
transformation = transformation \
|
|
260
|
+
* new_conic.hom(diagonal_matrix(multipliers))
|
|
261
|
+
if coeff[0].degree() % 2 == coeff[1].degree() % 2 and \
|
|
262
|
+
coeff[1].degree() % 2 == coeff[2].degree() % 2:
|
|
263
|
+
case = 0
|
|
264
|
+
else:
|
|
265
|
+
case = 1
|
|
266
|
+
|
|
267
|
+
t, = self.base_ring().base().gens() # t in F[t]
|
|
268
|
+
supp = []
|
|
269
|
+
roots = [[], [], []]
|
|
270
|
+
remove = None
|
|
271
|
+
# loop through the coefficients and find a root of f_i (as in
|
|
272
|
+
# [HC2006]) modulo each element in the coefficients' support
|
|
273
|
+
for i in (0, 1, 2):
|
|
274
|
+
supp.append(list(coeff[i].factor()))
|
|
275
|
+
for p in supp[i]:
|
|
276
|
+
if p[1] != 1:
|
|
277
|
+
raise ValueError("Expected factor of exponent 1.")
|
|
278
|
+
# Convert to monic factor
|
|
279
|
+
x = p[0] / list(p[0])[-1]
|
|
280
|
+
N = p[0].base_ring().extension(x, 'tbar')
|
|
281
|
+
R = PolynomialRing(N, 'u')
|
|
282
|
+
u, = R.gens()
|
|
283
|
+
# If p[0] has degree 1, sage might forget the "defining
|
|
284
|
+
# polynomial" of N, so we define our own modulo operation
|
|
285
|
+
if p[0].degree() == 1:
|
|
286
|
+
mod = t.parent().hom([-x[0]])
|
|
287
|
+
else:
|
|
288
|
+
mod = N
|
|
289
|
+
if i == 0:
|
|
290
|
+
x = -mod(coeff[2]) / mod(coeff[1])
|
|
291
|
+
elif i == 1:
|
|
292
|
+
x = -mod(coeff[0]) / mod(coeff[2])
|
|
293
|
+
else:
|
|
294
|
+
x = -mod(coeff[1]) / mod(coeff[0])
|
|
295
|
+
if x.is_square():
|
|
296
|
+
root = N(x.sqrt())
|
|
297
|
+
else:
|
|
298
|
+
return (False, None) if point else False
|
|
299
|
+
# if case == 0 and p[0] has degree 1, we switch to case
|
|
300
|
+
# 1 and remove this factor out of the support. In [HC2006]
|
|
301
|
+
# this is done later, in FindPoint.
|
|
302
|
+
if case == 0 and p[0].degree() == 1:
|
|
303
|
+
case = 1
|
|
304
|
+
# remove later so the loop iterator stays in place.
|
|
305
|
+
remove = (i, p)
|
|
306
|
+
else:
|
|
307
|
+
roots[i].append(root)
|
|
308
|
+
if remove:
|
|
309
|
+
supp[remove[0]].remove(remove[1])
|
|
310
|
+
supp = [[p[0] for p in supp[i]] for i in (0, 1, 2)]
|
|
311
|
+
|
|
312
|
+
if case == 0:
|
|
313
|
+
# Find a solution of (5) in [HC2006]
|
|
314
|
+
leading_conic = Conic(self.base_ring().base_ring(),
|
|
315
|
+
[coeff[0].leading_coefficient(),
|
|
316
|
+
coeff[1].leading_coefficient(),
|
|
317
|
+
coeff[2].leading_coefficient()])
|
|
318
|
+
has_point = leading_conic.has_rational_point(True)
|
|
319
|
+
if has_point[0]:
|
|
320
|
+
if point:
|
|
321
|
+
pt = new_conic.find_point(supp, roots, case,
|
|
322
|
+
has_point[1])
|
|
323
|
+
else:
|
|
324
|
+
pt = True
|
|
325
|
+
return (True, transformation(pt)) if point else True
|
|
326
|
+
else:
|
|
327
|
+
return (False, None) if point else False
|
|
328
|
+
# case == 1:
|
|
329
|
+
if point:
|
|
330
|
+
pt = new_conic.find_point(supp, roots, case)
|
|
331
|
+
else:
|
|
332
|
+
pt = True
|
|
333
|
+
return (True, transformation(pt)) if point else True
|
|
334
|
+
|
|
335
|
+
def _reduce_conic(self):
|
|
336
|
+
r"""
|
|
337
|
+
Return the reduced form of the conic, i.e. a conic with base field
|
|
338
|
+
`K=F(t)` and coefficients `a,b,c` such that `a,b,c \in F[t]`,
|
|
339
|
+
`\gcd(a,b)=\gcd(b,c)=\gcd(c,a)=1` and `abc` is square-free.
|
|
340
|
+
|
|
341
|
+
Assumes ``self`` is in diagonal form.
|
|
342
|
+
|
|
343
|
+
OUTPUT:
|
|
344
|
+
|
|
345
|
+
A tuple (coefficients, multipliers), the coefficients of the conic
|
|
346
|
+
in reduced form and multipliers `\lambda, \mu, \nu \in F(t)^*` such
|
|
347
|
+
that `(x,y,z) \in F(t)` is a solution of the reduced conic if and only
|
|
348
|
+
if `(\lambda x, \mu y, \nu z)` is a solution of ``self``.
|
|
349
|
+
|
|
350
|
+
ALGORITHM:
|
|
351
|
+
|
|
352
|
+
The algorithm used is the algorithm ReduceConic in [HC2006]_.
|
|
353
|
+
|
|
354
|
+
EXAMPLES::
|
|
355
|
+
|
|
356
|
+
sage: K.<t> = FractionField(PolynomialRing(QQ, 't'))
|
|
357
|
+
sage: C = Conic(K, [t^2 - 2, 2*t^3, -2*t^3 - 13*t^2 - 2*t + 18])
|
|
358
|
+
sage: C._reduce_conic()
|
|
359
|
+
([t^2 - 2, 2*t, -2*t^3 - 13*t^2 - 2*t + 18], [t, 1, t])
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
# start with removing fractions
|
|
363
|
+
coeff = [self.coefficients()[0], self.coefficients()[3],
|
|
364
|
+
self.coefficients()[5]]
|
|
365
|
+
coeff = lcm(lcm(coeff[0].denominator(), coeff[1].denominator()),
|
|
366
|
+
coeff[2].denominator()) * vector(coeff)
|
|
367
|
+
# go to base ring of fraction field
|
|
368
|
+
coeff = [self.base().base()(x) for x in coeff]
|
|
369
|
+
coeff = vector(coeff) / gcd(coeff)
|
|
370
|
+
# remove common divisors
|
|
371
|
+
labda = mu = nu = 1
|
|
372
|
+
g1 = g2 = g3 = 0
|
|
373
|
+
ca, cb, cc = coeff
|
|
374
|
+
while g1 != 1 or g2 != 1 or g3 != 1:
|
|
375
|
+
g1 = gcd(ca, cb)
|
|
376
|
+
ca = ca / g1
|
|
377
|
+
cb = cb / g1
|
|
378
|
+
cc = cc * g1
|
|
379
|
+
nu = g1 * nu
|
|
380
|
+
g2 = gcd(ca, cc)
|
|
381
|
+
ca = ca / g2
|
|
382
|
+
cc = cc / g2
|
|
383
|
+
cb = cb * g2
|
|
384
|
+
mu = g2 * mu
|
|
385
|
+
g3 = gcd(cb, cc)
|
|
386
|
+
cb = cb / g3
|
|
387
|
+
cc = cc / g3
|
|
388
|
+
ca = ca * g3
|
|
389
|
+
labda = g3 * labda
|
|
390
|
+
coeff = [ca, cb, cc]
|
|
391
|
+
multipliers = [labda, mu, nu]
|
|
392
|
+
|
|
393
|
+
# remove squares
|
|
394
|
+
for i, x in enumerate(coeff):
|
|
395
|
+
if isinstance(x.parent(), FractionField_generic):
|
|
396
|
+
# go to base ring of fraction field
|
|
397
|
+
x = self.base().base()(x)
|
|
398
|
+
|
|
399
|
+
try:
|
|
400
|
+
decom = x.squarefree_decomposition()
|
|
401
|
+
except (NotImplementedError, AttributeError):
|
|
402
|
+
decom = x.factor()
|
|
403
|
+
x = decom.unit()
|
|
404
|
+
x2 = 1
|
|
405
|
+
for factor in decom:
|
|
406
|
+
if factor[1] > 1:
|
|
407
|
+
if factor[1] % 2 == 0:
|
|
408
|
+
x2 *= factor[0] ** (factor[1] // 2)
|
|
409
|
+
else:
|
|
410
|
+
x *= factor[0]
|
|
411
|
+
x2 *= factor[0] ** ((factor[1] - 1) // 2)
|
|
412
|
+
else:
|
|
413
|
+
x *= factor[0]
|
|
414
|
+
for j, y in enumerate(multipliers):
|
|
415
|
+
if j != i:
|
|
416
|
+
multipliers[j] = y * x2
|
|
417
|
+
coeff[i] = self.base_ring().base().coerce(x)
|
|
418
|
+
|
|
419
|
+
return (coeff, multipliers)
|
|
420
|
+
|
|
421
|
+
def find_point(self, supports, roots, case, solution=0):
|
|
422
|
+
r"""
|
|
423
|
+
Given a solubility certificate like in [HC2006]_, find a point on
|
|
424
|
+
``self``. Assumes ``self`` is in reduced form (see [HC2006]_ for a
|
|
425
|
+
definition).
|
|
426
|
+
|
|
427
|
+
If you don't have a solubility certificate and just want to find a
|
|
428
|
+
point, use the function :meth:`has_rational_point` instead.
|
|
429
|
+
|
|
430
|
+
INPUT:
|
|
431
|
+
|
|
432
|
+
- ``self`` -- conic in reduced form
|
|
433
|
+
- ``supports`` -- 3-tuple where ``supports[i]`` is a list of all monic
|
|
434
|
+
irreducible `p \in F[t]` that divide the `i`-th of the 3 coefficients
|
|
435
|
+
- ``roots`` -- 3-tuple containing lists of roots of all elements of
|
|
436
|
+
``supports[i]``, in the same order
|
|
437
|
+
- ``case`` -- 1 or 0, as in [HC2006]_
|
|
438
|
+
- ``solution`` -- (default: 0) a solution of (5) in [HC2006]_, if
|
|
439
|
+
``case`` = 0, 0 otherwise
|
|
440
|
+
|
|
441
|
+
OUTPUT:
|
|
442
|
+
|
|
443
|
+
A point `(x,y,z) \in F(t)` of ``self``. Output is undefined when the
|
|
444
|
+
input solubility certificate is incorrect.
|
|
445
|
+
|
|
446
|
+
ALGORITHM:
|
|
447
|
+
|
|
448
|
+
The algorithm used is the algorithm FindPoint in [HC2006]_, with
|
|
449
|
+
a simplification from [Ack2016]_.
|
|
450
|
+
|
|
451
|
+
EXAMPLES::
|
|
452
|
+
|
|
453
|
+
sage: K.<t> = FractionField(QQ['t'])
|
|
454
|
+
sage: C = Conic(K, [t^2 - 2, 2*t^3, -2*t^3 - 13*t^2 - 2*t + 18])
|
|
455
|
+
sage: C.has_rational_point(point=True) # indirect test # needs sage.libs.singular
|
|
456
|
+
(True, (-3 : (t + 1)/t : 1))
|
|
457
|
+
|
|
458
|
+
Different solubility certificates give different points::
|
|
459
|
+
|
|
460
|
+
sage: # needs sage.rings.number_field
|
|
461
|
+
sage: K.<t> = PolynomialRing(QQ, 't')
|
|
462
|
+
sage: C = Conic(K, [t^2 - 2, 2*t, -2*t^3 - 13*t^2 - 2*t + 18])
|
|
463
|
+
sage: supp = [[t^2 - 2], [t], [t^3 + 13/2*t^2 + t - 9]]
|
|
464
|
+
sage: tbar1 = QQ.extension(supp[0][0], 'tbar').gens()[0]
|
|
465
|
+
sage: tbar2 = QQ.extension(supp[1][0], 'tbar').gens()[0]
|
|
466
|
+
sage: tbar3 = QQ.extension(supp[2][0], 'tbar').gens()[0]
|
|
467
|
+
sage: roots = [[tbar1 + 1], [1/3*tbar2^0], [2/3*tbar3^2 + 11/3*tbar3 - 3]]
|
|
468
|
+
sage: C.find_point(supp, roots, 1)
|
|
469
|
+
(3 : t + 1 : 1)
|
|
470
|
+
sage: roots = [[-tbar1 - 1], [-1/3*tbar2^0], [-2/3*tbar3^2 - 11/3*tbar3 + 3]]
|
|
471
|
+
sage: C.find_point(supp, roots, 1)
|
|
472
|
+
(3 : -t - 1 : 1)
|
|
473
|
+
"""
|
|
474
|
+
Ft = self.base().base()
|
|
475
|
+
F = Ft.base()
|
|
476
|
+
t, = Ft.gens()
|
|
477
|
+
coefficients = [Ft(self.coefficients()[0]), Ft(self.coefficients()[3]),
|
|
478
|
+
Ft(self.coefficients()[5])]
|
|
479
|
+
deg = [coefficients[0].degree(), coefficients[1].degree(),
|
|
480
|
+
coefficients[2].degree()]
|
|
481
|
+
# definitions as in [HC2006] and [Ack2016]
|
|
482
|
+
A = ((deg[1] + deg[2]) / 2).ceil() - case
|
|
483
|
+
B = ((deg[2] + deg[0]) / 2).ceil() - case
|
|
484
|
+
C = ((deg[0] + deg[1]) / 2).ceil() - case
|
|
485
|
+
|
|
486
|
+
# For all roots as calculated by has_rational_point(), we create
|
|
487
|
+
# a system of linear equations. As in [Ack2016], we do this
|
|
488
|
+
# by calculating the matrices for all phi_p, with basis consisting
|
|
489
|
+
# of monomials of x, y and z in the space V of potential solutions:
|
|
490
|
+
# t^0, ..., t^A, t^0, ..., t^B and t^0, ..., t^C.
|
|
491
|
+
phi = []
|
|
492
|
+
for (i, p) in enumerate(supports[0]):
|
|
493
|
+
# lift to F[t] and map to R, with R as defined above
|
|
494
|
+
if roots[0][i].parent().is_finite():
|
|
495
|
+
root = roots[0][i].polynomial()
|
|
496
|
+
else:
|
|
497
|
+
root = roots[0][i].lift()
|
|
498
|
+
alpha = root.parent().hom([t])(root)
|
|
499
|
+
d = p.degree()
|
|
500
|
+
# Calculate y - alpha*z mod p for all basis vectors
|
|
501
|
+
phi_p = [[] for i in range(A + B + C + 4)]
|
|
502
|
+
phi_p[0:A + 1] = [vector(F, d)] * (A + 1)
|
|
503
|
+
phi_p[A + 1] = vector(F, d, {0: F(1)})
|
|
504
|
+
lastpoly = F(1)
|
|
505
|
+
for n in range(B):
|
|
506
|
+
lastpoly = (lastpoly * t) % p
|
|
507
|
+
phi_p[A + 2 + n] = vector(F, d, lastpoly.monomial_coefficients())
|
|
508
|
+
lastpoly = -alpha % p
|
|
509
|
+
phi_p[A + B + 2] = vector(F, d, lastpoly.monomial_coefficients())
|
|
510
|
+
for n in range(C):
|
|
511
|
+
lastpoly = (lastpoly * t) % p
|
|
512
|
+
phi_p[A + B + 3 + n] = vector(F, d, lastpoly.monomial_coefficients())
|
|
513
|
+
phi_p[A + B + C + 3] = vector(F, d)
|
|
514
|
+
phi.append(matrix(phi_p).transpose())
|
|
515
|
+
for (i, p) in enumerate(supports[1]):
|
|
516
|
+
if roots[1][i].parent().is_finite():
|
|
517
|
+
root = roots[1][i].polynomial()
|
|
518
|
+
else:
|
|
519
|
+
root = roots[1][i].lift()
|
|
520
|
+
alpha = root.parent().hom([t])(root)
|
|
521
|
+
d = p.degree()
|
|
522
|
+
# Calculate z - alpha*x mod p for all basis vectors
|
|
523
|
+
phi_p = [[] for i in range(A + B + C + 4)]
|
|
524
|
+
phi_p[A + 1:A + B + 2] = [vector(F, d)] * (B + 1)
|
|
525
|
+
phi_p[A + B + 2] = vector(F, d, {0: F(1)})
|
|
526
|
+
lastpoly = F(1)
|
|
527
|
+
for n in range(C):
|
|
528
|
+
lastpoly = (lastpoly * t) % p
|
|
529
|
+
phi_p[A + B + 3 + n] = vector(F, d, lastpoly.monomial_coefficients())
|
|
530
|
+
lastpoly = -alpha % p
|
|
531
|
+
phi_p[0] = vector(F, d, lastpoly.monomial_coefficients())
|
|
532
|
+
for n in range(A):
|
|
533
|
+
lastpoly = (lastpoly * t) % p
|
|
534
|
+
phi_p[1 + n] = vector(F, d, lastpoly.monomial_coefficients())
|
|
535
|
+
phi_p[A + B + C + 3] = vector(F, d)
|
|
536
|
+
phi.append(matrix(phi_p).transpose())
|
|
537
|
+
for (i, p) in enumerate(supports[2]):
|
|
538
|
+
if roots[2][i].parent().is_finite():
|
|
539
|
+
root = roots[2][i].polynomial()
|
|
540
|
+
else:
|
|
541
|
+
root = roots[2][i].lift()
|
|
542
|
+
alpha = root.parent().hom([t])(root)
|
|
543
|
+
d = p.degree()
|
|
544
|
+
# Calculate x - alpha*y mod p for all basis vectors
|
|
545
|
+
phi_p = [[] for i in range(A + B + C + 4)]
|
|
546
|
+
phi_p[A + B + 2:A + B + C + 3] = [vector(F, d)] * (C + 1)
|
|
547
|
+
phi_p[0] = vector(F, d, {0: F(1)})
|
|
548
|
+
lastpoly = F(1)
|
|
549
|
+
for n in range(A):
|
|
550
|
+
lastpoly = (lastpoly * t) % p
|
|
551
|
+
phi_p[1 + n] = vector(F, d, lastpoly.monomial_coefficients())
|
|
552
|
+
lastpoly = -alpha % p
|
|
553
|
+
phi_p[A + 1] = vector(F, d, lastpoly.monomial_coefficients())
|
|
554
|
+
for n in range(B):
|
|
555
|
+
lastpoly = (lastpoly * t) % p
|
|
556
|
+
phi_p[A + 2 + n] = vector(F, d, lastpoly.monomial_coefficients())
|
|
557
|
+
phi_p[A + B + C + 3] = vector(F, d)
|
|
558
|
+
phi.append(matrix(phi_p).transpose())
|
|
559
|
+
if case == 0:
|
|
560
|
+
# We need three more equations
|
|
561
|
+
lx = Ft(solution[0]).leading_coefficient()
|
|
562
|
+
ly = Ft(solution[1]).leading_coefficient()
|
|
563
|
+
lz = Ft(solution[2]).leading_coefficient()
|
|
564
|
+
ABC = A + B + C
|
|
565
|
+
phi.append(matrix([vector(F, ABC + 4, {A: 1, ABC + 3: -lx}),
|
|
566
|
+
vector(F, ABC + 4, {A + B + 1: 1, ABC + 3: -ly}),
|
|
567
|
+
vector(F, ABC + 4, {ABC + 2: 1, ABC + 3: -lz})]))
|
|
568
|
+
# Create the final matrix which we will solve
|
|
569
|
+
M = block_matrix(phi, ncols=1, subdivide=False)
|
|
570
|
+
solution_space = M.right_kernel()
|
|
571
|
+
for v in solution_space.basis():
|
|
572
|
+
if v[:A + B + C + 3] != 0:
|
|
573
|
+
# we do not want to return a trivial solution
|
|
574
|
+
X = Ft(list(v[:A + 1]))
|
|
575
|
+
Y = Ft(list(v[A + 1:A + B + 2]))
|
|
576
|
+
Z = Ft(list(v[A + B + 2:A + B + C + 3]))
|
|
577
|
+
return self.point([X, Y, Z])
|
|
578
|
+
|
|
579
|
+
raise RuntimeError("No solution has been found: possibly incorrect "
|
|
580
|
+
"solubility certificate.")
|