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,1296 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
r"""
|
|
3
|
+
Projective plane conics over a field
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- Marco Streng (2010-07-20)
|
|
8
|
+
|
|
9
|
+
- Nick Alexander (2008-01-08)
|
|
10
|
+
"""
|
|
11
|
+
# *****************************************************************************
|
|
12
|
+
# Copyright (C) 2008 Nick Alexander <ncalexander@gmail.com>
|
|
13
|
+
# Copyright (C) 2009/2010 Marco Streng <marco.streng@gmail.com>
|
|
14
|
+
#
|
|
15
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
16
|
+
#
|
|
17
|
+
# This code is distributed in the hope that it will be useful,
|
|
18
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
20
|
+
# General Public License for more details.
|
|
21
|
+
#
|
|
22
|
+
# The full text of the GPL is available at:
|
|
23
|
+
#
|
|
24
|
+
# http://www.gnu.org/licenses/
|
|
25
|
+
# *****************************************************************************
|
|
26
|
+
|
|
27
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
28
|
+
|
|
29
|
+
import sage.rings.abc
|
|
30
|
+
|
|
31
|
+
from sage.modules.free_module_element import vector
|
|
32
|
+
from sage.structure.sequence import Sequence
|
|
33
|
+
from sage.structure.element import Vector
|
|
34
|
+
from sage.schemes.projective.projective_space import ProjectiveSpace
|
|
35
|
+
from sage.matrix.constructor import matrix
|
|
36
|
+
from sage.structure.element import Matrix
|
|
37
|
+
|
|
38
|
+
from sage.schemes.curves.projective_curve import ProjectivePlaneCurve_field
|
|
39
|
+
|
|
40
|
+
from sage.categories.fields import Fields
|
|
41
|
+
_Fields = Fields()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ProjectiveConic_field(ProjectivePlaneCurve_field):
|
|
45
|
+
r"""
|
|
46
|
+
Create a projective plane conic curve over a field.
|
|
47
|
+
See ``Conic`` for full documentation.
|
|
48
|
+
|
|
49
|
+
EXAMPLES::
|
|
50
|
+
|
|
51
|
+
sage: K = FractionField(PolynomialRing(QQ, 't'))
|
|
52
|
+
sage: P.<X, Y, Z> = K[]
|
|
53
|
+
sage: Conic(X^2 + Y^2 - Z^2)
|
|
54
|
+
Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t
|
|
55
|
+
over Rational Field defined by X^2 + Y^2 - Z^2
|
|
56
|
+
|
|
57
|
+
TESTS::
|
|
58
|
+
|
|
59
|
+
sage: K = FractionField(PolynomialRing(QQ, 't'))
|
|
60
|
+
sage: Conic([K(1), 1, -1])._test_pickling()
|
|
61
|
+
"""
|
|
62
|
+
def __init__(self, A, f):
|
|
63
|
+
r"""
|
|
64
|
+
See ``Conic`` for full documentation.
|
|
65
|
+
|
|
66
|
+
EXAMPLES:
|
|
67
|
+
|
|
68
|
+
::
|
|
69
|
+
|
|
70
|
+
sage: c = Conic([1, 1, 1]); c
|
|
71
|
+
Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
|
|
72
|
+
"""
|
|
73
|
+
super().__init__(A, f)
|
|
74
|
+
self._coefficients = [f[(2, 0, 0)], f[(1, 1, 0)], f[(1, 0, 1)],
|
|
75
|
+
f[(0, 2, 0)], f[(0, 1, 1)], f[(0, 0, 2)]]
|
|
76
|
+
self._parametrization = None
|
|
77
|
+
self._diagonal_matrix = None
|
|
78
|
+
|
|
79
|
+
self._rational_point = None
|
|
80
|
+
|
|
81
|
+
def _repr_type(self):
|
|
82
|
+
r"""
|
|
83
|
+
Return ``'Projective Conic'``, which is the first part of the
|
|
84
|
+
plain text representation of this object as output by
|
|
85
|
+
the function ``_repr_`` of the class ``Curve_generic``.
|
|
86
|
+
|
|
87
|
+
EXAMPLES::
|
|
88
|
+
|
|
89
|
+
sage: c = Conic([1, 1, 1]); c
|
|
90
|
+
Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
|
|
91
|
+
sage: c._repr_()
|
|
92
|
+
'Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2'
|
|
93
|
+
sage: c._repr_type()
|
|
94
|
+
'Projective Conic'
|
|
95
|
+
"""
|
|
96
|
+
return "Projective Conic"
|
|
97
|
+
|
|
98
|
+
def base_extend(self, S):
|
|
99
|
+
r"""
|
|
100
|
+
Return the conic over ``S`` given by the same equation as ``self``.
|
|
101
|
+
|
|
102
|
+
EXAMPLES::
|
|
103
|
+
|
|
104
|
+
sage: c = Conic([1, 1, 1]); c
|
|
105
|
+
Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
|
|
106
|
+
sage: c.has_rational_point() # needs sage.libs.pari
|
|
107
|
+
False
|
|
108
|
+
sage: d = c.base_extend(QuadraticField(-1, 'i')); d # needs sage.rings.number_field
|
|
109
|
+
Projective Conic Curve over Number Field in i
|
|
110
|
+
with defining polynomial x^2 + 1 with i = 1*I defined by x^2 + y^2 + z^2
|
|
111
|
+
sage: d.rational_point(algorithm='rnfisnorm') # needs sage.rings.number_field
|
|
112
|
+
(i : 1 : 0)
|
|
113
|
+
"""
|
|
114
|
+
if S in _Fields:
|
|
115
|
+
B = self.base_ring()
|
|
116
|
+
if B == S:
|
|
117
|
+
return self
|
|
118
|
+
if not S.has_coerce_map_from(B):
|
|
119
|
+
raise ValueError("No natural map from the base ring of self "
|
|
120
|
+
"(= %s) to S (= %s)" % (self, S))
|
|
121
|
+
from .constructor import Conic
|
|
122
|
+
con = Conic([S(c) for c in self.coefficients()],
|
|
123
|
+
self.variable_names())
|
|
124
|
+
if self._rational_point is not None:
|
|
125
|
+
pt = [S(c) for c in Sequence(self._rational_point)]
|
|
126
|
+
if not pt == [0, 0, 0]:
|
|
127
|
+
# The following line stores the point in the cache
|
|
128
|
+
# if (and only if) there is no point in the cache.
|
|
129
|
+
pt = con.point(pt)
|
|
130
|
+
return con
|
|
131
|
+
return super().base_extend(S)
|
|
132
|
+
|
|
133
|
+
def cache_point(self, p):
|
|
134
|
+
r"""
|
|
135
|
+
Replace the point in the cache of ``self`` by ``p`` for use
|
|
136
|
+
by :meth:`rational_point` and :meth:`parametrization`.
|
|
137
|
+
|
|
138
|
+
EXAMPLES::
|
|
139
|
+
|
|
140
|
+
sage: c = Conic([1, -1, 1])
|
|
141
|
+
sage: c.point([15, 17, 8])
|
|
142
|
+
(15/8 : 17/8 : 1)
|
|
143
|
+
sage: c.rational_point()
|
|
144
|
+
(15/8 : 17/8 : 1)
|
|
145
|
+
|
|
146
|
+
sage: # needs sage.libs.pari
|
|
147
|
+
sage: c.cache_point(c.rational_point(read_cache=False))
|
|
148
|
+
sage: c.rational_point()
|
|
149
|
+
(-1 : 1 : 0)
|
|
150
|
+
"""
|
|
151
|
+
if isinstance(p, (tuple, list)):
|
|
152
|
+
p = self.point(p)
|
|
153
|
+
self._rational_point = p
|
|
154
|
+
|
|
155
|
+
def coefficients(self):
|
|
156
|
+
r"""
|
|
157
|
+
Give a the `6` coefficients of the conic ``self``
|
|
158
|
+
in lexicographic order.
|
|
159
|
+
|
|
160
|
+
EXAMPLES::
|
|
161
|
+
|
|
162
|
+
sage: Conic(QQ, [1,2,3,4,5,6]).coefficients()
|
|
163
|
+
[1, 2, 3, 4, 5, 6]
|
|
164
|
+
|
|
165
|
+
sage: P.<x,y,z> = GF(13)[]
|
|
166
|
+
sage: a = Conic(x^2 + 5*x*y + y^2 + z^2).coefficients(); a
|
|
167
|
+
[1, 5, 0, 1, 0, 1]
|
|
168
|
+
sage: Conic(a)
|
|
169
|
+
Projective Conic Curve over Finite Field of size 13
|
|
170
|
+
defined by x^2 + 5*x*y + y^2 + z^2
|
|
171
|
+
"""
|
|
172
|
+
return self._coefficients
|
|
173
|
+
|
|
174
|
+
def derivative_matrix(self):
|
|
175
|
+
r"""
|
|
176
|
+
Give the derivative of the defining polynomial of
|
|
177
|
+
the conic ``self``, which is a linear map,
|
|
178
|
+
as a `3 \times 3` matrix.
|
|
179
|
+
|
|
180
|
+
EXAMPLES:
|
|
181
|
+
|
|
182
|
+
In characteristic different from `2`, the
|
|
183
|
+
derivative matrix is twice the symmetric matrix:
|
|
184
|
+
|
|
185
|
+
::
|
|
186
|
+
|
|
187
|
+
sage: c = Conic(QQ, [1,1,1,1,1,0])
|
|
188
|
+
sage: c.symmetric_matrix()
|
|
189
|
+
[ 1 1/2 1/2]
|
|
190
|
+
[1/2 1 1/2]
|
|
191
|
+
[1/2 1/2 0]
|
|
192
|
+
sage: c.derivative_matrix()
|
|
193
|
+
[2 1 1]
|
|
194
|
+
[1 2 1]
|
|
195
|
+
[1 1 0]
|
|
196
|
+
|
|
197
|
+
An example in characteristic `2`::
|
|
198
|
+
|
|
199
|
+
sage: P.<t> = GF(2)[]
|
|
200
|
+
sage: c = Conic([t, 1, t^2, 1, 1, 0]); c # needs sage.libs.ntl
|
|
201
|
+
Projective Conic Curve over Fraction Field of Univariate
|
|
202
|
+
Polynomial Ring in t over Finite Field of size 2 (using GF2X)
|
|
203
|
+
defined by t*x^2 + x*y + y^2 + (t^2)*x*z + y*z
|
|
204
|
+
sage: c.is_smooth()
|
|
205
|
+
True
|
|
206
|
+
sage: c.derivative_matrix()
|
|
207
|
+
[ 0 1 t^2]
|
|
208
|
+
[ 1 0 1]
|
|
209
|
+
[t^2 1 0]
|
|
210
|
+
"""
|
|
211
|
+
a, b, c, d, e, f = self.coefficients()
|
|
212
|
+
return matrix([[2 * a, b, c],
|
|
213
|
+
[b, 2 * d, e],
|
|
214
|
+
[c, e, 2 * f]])
|
|
215
|
+
|
|
216
|
+
def determinant(self):
|
|
217
|
+
r"""
|
|
218
|
+
Return the determinant of the symmetric matrix that defines
|
|
219
|
+
the conic ``self``.
|
|
220
|
+
|
|
221
|
+
This is defined only if the base field has characteristic
|
|
222
|
+
different from `2`.
|
|
223
|
+
|
|
224
|
+
EXAMPLES:
|
|
225
|
+
|
|
226
|
+
::
|
|
227
|
+
|
|
228
|
+
sage: C = Conic([1,2,3,4,5,6])
|
|
229
|
+
sage: C.determinant()
|
|
230
|
+
41/4
|
|
231
|
+
sage: C.symmetric_matrix().determinant()
|
|
232
|
+
41/4
|
|
233
|
+
|
|
234
|
+
Determinants are only defined in characteristic different from `2`::
|
|
235
|
+
|
|
236
|
+
sage: C = Conic(GF(2), [1, 1, 1, 1, 1, 0])
|
|
237
|
+
sage: C.is_smooth()
|
|
238
|
+
True
|
|
239
|
+
sage: C.determinant()
|
|
240
|
+
Traceback (most recent call last):
|
|
241
|
+
...
|
|
242
|
+
ValueError: The conic self (= Projective Conic Curve over Finite Field
|
|
243
|
+
of size 2 defined by x^2 + x*y + y^2 + x*z + y*z) has no symmetric matrix
|
|
244
|
+
because the base field has characteristic 2
|
|
245
|
+
"""
|
|
246
|
+
return self.symmetric_matrix().determinant()
|
|
247
|
+
|
|
248
|
+
def diagonal_matrix(self):
|
|
249
|
+
r"""
|
|
250
|
+
Return a diagonal matrix `D` and a matrix `T` such that `T^t A T = D`
|
|
251
|
+
holds, where `(x, y, z) A (x, y, z)^t` is the defining polynomial
|
|
252
|
+
of the conic ``self``.
|
|
253
|
+
|
|
254
|
+
EXAMPLES:
|
|
255
|
+
|
|
256
|
+
::
|
|
257
|
+
|
|
258
|
+
sage: c = Conic(QQ, [1,2,3,4,5,6])
|
|
259
|
+
sage: d, t = c.diagonal_matrix(); d, t
|
|
260
|
+
(
|
|
261
|
+
[ 1 0 0] [ 1 -1 -7/6]
|
|
262
|
+
[ 0 3 0] [ 0 1 -1/3]
|
|
263
|
+
[ 0 0 41/12], [ 0 0 1]
|
|
264
|
+
)
|
|
265
|
+
sage: t.transpose()*c.symmetric_matrix()*t
|
|
266
|
+
[ 1 0 0]
|
|
267
|
+
[ 0 3 0]
|
|
268
|
+
[ 0 0 41/12]
|
|
269
|
+
|
|
270
|
+
Diagonal matrices are only defined in characteristic different
|
|
271
|
+
from `2`:
|
|
272
|
+
|
|
273
|
+
::
|
|
274
|
+
|
|
275
|
+
sage: # needs sage.rings.finite_rings
|
|
276
|
+
sage: c = Conic(GF(4, 'a'), [0, 1, 1, 1, 1, 1])
|
|
277
|
+
sage: c.is_smooth()
|
|
278
|
+
True
|
|
279
|
+
sage: c.diagonal_matrix()
|
|
280
|
+
Traceback (most recent call last):
|
|
281
|
+
...
|
|
282
|
+
ValueError: The conic self (= Projective Conic Curve over Finite Field
|
|
283
|
+
in a of size 2^2 defined by x*y + y^2 + x*z + y*z + z^2) has
|
|
284
|
+
no symmetric matrix because the base field has characteristic 2
|
|
285
|
+
"""
|
|
286
|
+
A = self.symmetric_matrix()
|
|
287
|
+
B = self.base_ring()
|
|
288
|
+
basis = [vector(B, {2: 0, i: 1}) for i in range(3)]
|
|
289
|
+
for i in range(3):
|
|
290
|
+
zerovalue = (basis[i]*A*basis[i].column() == 0)
|
|
291
|
+
if zerovalue:
|
|
292
|
+
for j in range(i+1, 3):
|
|
293
|
+
if basis[j]*A*basis[j].column() != 0:
|
|
294
|
+
b = basis[i]
|
|
295
|
+
basis[i] = basis[j]
|
|
296
|
+
basis[j] = b
|
|
297
|
+
zerovalue = False
|
|
298
|
+
if zerovalue:
|
|
299
|
+
for j in range(i+1, 3):
|
|
300
|
+
if basis[i]*A*basis[j].column() != 0:
|
|
301
|
+
basis[i] = basis[i]+basis[j]
|
|
302
|
+
zerovalue = False
|
|
303
|
+
if not zerovalue:
|
|
304
|
+
l = (basis[i]*A*basis[i].column())
|
|
305
|
+
for j in range(i+1, 3):
|
|
306
|
+
basis[j] = basis[j] - \
|
|
307
|
+
(basis[i]*A*basis[j].column())/l * basis[i]
|
|
308
|
+
T = matrix(basis).transpose()
|
|
309
|
+
return T.transpose()*A*T, T
|
|
310
|
+
|
|
311
|
+
def diagonalization(self, names=None):
|
|
312
|
+
r"""
|
|
313
|
+
Return a diagonal conic `C`, an isomorphism of schemes `M: C` -> ``self``
|
|
314
|
+
and the inverse `N` of `M`.
|
|
315
|
+
|
|
316
|
+
EXAMPLES::
|
|
317
|
+
|
|
318
|
+
sage: Conic(GF(5), [1,0,1,1,0,1]).diagonalization()
|
|
319
|
+
(Projective Conic Curve over Finite Field of size 5
|
|
320
|
+
defined by x^2 + y^2 + 2*z^2,
|
|
321
|
+
Scheme morphism:
|
|
322
|
+
From: Projective Conic Curve over Finite Field of size 5
|
|
323
|
+
defined by x^2 + y^2 + 2*z^2
|
|
324
|
+
To: Projective Conic Curve over Finite Field of size 5
|
|
325
|
+
defined by x^2 + y^2 + x*z + z^2
|
|
326
|
+
Defn: Defined on coordinates by sending (x : y : z) to (x + 2*z : y : z),
|
|
327
|
+
Scheme morphism:
|
|
328
|
+
From: Projective Conic Curve over Finite Field of size 5
|
|
329
|
+
defined by x^2 + y^2 + x*z + z^2
|
|
330
|
+
To: Projective Conic Curve over Finite Field of size 5
|
|
331
|
+
defined by x^2 + y^2 + 2*z^2
|
|
332
|
+
Defn: Defined on coordinates by sending (x : y : z) to (x - 2*z : y : z))
|
|
333
|
+
|
|
334
|
+
The diagonalization is only defined in characteristic different
|
|
335
|
+
from 2:
|
|
336
|
+
|
|
337
|
+
::
|
|
338
|
+
|
|
339
|
+
sage: Conic(GF(2), [1,1,1,1,1,0]).diagonalization()
|
|
340
|
+
Traceback (most recent call last):
|
|
341
|
+
...
|
|
342
|
+
ValueError: The conic self (= Projective Conic Curve over Finite Field
|
|
343
|
+
of size 2 defined by x^2 + x*y + y^2 + x*z + y*z) has no symmetric matrix
|
|
344
|
+
because the base field has characteristic 2
|
|
345
|
+
|
|
346
|
+
An example over a global function field:
|
|
347
|
+
|
|
348
|
+
::
|
|
349
|
+
|
|
350
|
+
sage: K = FractionField(PolynomialRing(GF(7), 't'))
|
|
351
|
+
sage: (t,) = K.gens()
|
|
352
|
+
sage: C = Conic(K, [t/2,0, 1, 2, 0, 3])
|
|
353
|
+
sage: C.diagonalization()
|
|
354
|
+
(Projective Conic Curve over Fraction Field of Univariate
|
|
355
|
+
Polynomial Ring in t over Finite Field of size 7
|
|
356
|
+
defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2,
|
|
357
|
+
Scheme morphism:
|
|
358
|
+
From: Projective Conic Curve over Fraction Field of Univariate
|
|
359
|
+
Polynomial Ring in t over Finite Field of size 7
|
|
360
|
+
defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2
|
|
361
|
+
To: Projective Conic Curve over Fraction Field of Univariate
|
|
362
|
+
Polynomial Ring in t over Finite Field of size 7
|
|
363
|
+
defined by (-3*t)*x^2 + 2*y^2 + x*z + 3*z^2
|
|
364
|
+
Defn: Defined on coordinates by sending (x : y : z) to (x - 1/t*z : y : z),
|
|
365
|
+
Scheme morphism:
|
|
366
|
+
From: Projective Conic Curve over Fraction Field of Univariate
|
|
367
|
+
Polynomial Ring in t over Finite Field of size 7
|
|
368
|
+
defined by (-3*t)*x^2 + 2*y^2 + x*z + 3*z^2
|
|
369
|
+
To: Projective Conic Curve over Fraction Field of Univariate
|
|
370
|
+
Polynomial Ring in t over Finite Field of size 7
|
|
371
|
+
defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2
|
|
372
|
+
Defn: Defined on coordinates by sending (x : y : z) to (x + 1/t*z : y : z))
|
|
373
|
+
"""
|
|
374
|
+
if names is None:
|
|
375
|
+
names = self.defining_polynomial().parent().variable_names()
|
|
376
|
+
from .constructor import Conic
|
|
377
|
+
D, T = self.diagonal_matrix()
|
|
378
|
+
con = Conic(D, names=names)
|
|
379
|
+
return con, con.hom(T, self), self.hom(T.inverse(), con)
|
|
380
|
+
|
|
381
|
+
def gens(self) -> tuple:
|
|
382
|
+
r"""
|
|
383
|
+
Return the generators of the coordinate ring of ``self``.
|
|
384
|
+
|
|
385
|
+
EXAMPLES:
|
|
386
|
+
|
|
387
|
+
::
|
|
388
|
+
|
|
389
|
+
sage: P.<x,y,z> = QQ[]
|
|
390
|
+
sage: c = Conic(x^2 + y^2 + z^2)
|
|
391
|
+
sage: c.gens() # needs sage.libs.singular
|
|
392
|
+
(xbar, ybar, zbar)
|
|
393
|
+
sage: c.defining_polynomial()(c.gens()) # needs sage.libs.singular
|
|
394
|
+
0
|
|
395
|
+
|
|
396
|
+
The function ``gens()`` is required for the following construction:
|
|
397
|
+
|
|
398
|
+
::
|
|
399
|
+
|
|
400
|
+
sage: C.<a,b,c> = Conic(GF(3), [1, 1, 1]); C # needs sage.libs.singular
|
|
401
|
+
Projective Conic Curve over
|
|
402
|
+
Finite Field of size 3 defined by a^2 + b^2 + c^2
|
|
403
|
+
"""
|
|
404
|
+
return self.coordinate_ring().gens()
|
|
405
|
+
|
|
406
|
+
def has_rational_point(self, point=False,
|
|
407
|
+
algorithm='default', read_cache=True):
|
|
408
|
+
r"""
|
|
409
|
+
Return ``True`` if and only if the conic ``self``
|
|
410
|
+
has a point over its base field `B`.
|
|
411
|
+
|
|
412
|
+
If ``point`` is ``True``, then returns a second output, which is
|
|
413
|
+
a rational point if one exists.
|
|
414
|
+
|
|
415
|
+
Points are cached whenever they are found. Cached information
|
|
416
|
+
is used if and only if ``read_cache`` is ``True``.
|
|
417
|
+
|
|
418
|
+
ALGORITHM:
|
|
419
|
+
|
|
420
|
+
The parameter ``algorithm`` specifies the algorithm
|
|
421
|
+
to be used:
|
|
422
|
+
|
|
423
|
+
- ``'default'`` -- if the base field is real or complex,
|
|
424
|
+
use an elementary native Sage implementation
|
|
425
|
+
|
|
426
|
+
- ``'magma'`` (requires Magma to be installed) --
|
|
427
|
+
delegates the task to the Magma computer algebra
|
|
428
|
+
system
|
|
429
|
+
|
|
430
|
+
EXAMPLES::
|
|
431
|
+
|
|
432
|
+
sage: Conic(RR, [1, 1, 1]).has_rational_point()
|
|
433
|
+
False
|
|
434
|
+
sage: Conic(CC, [1, 1, 1]).has_rational_point()
|
|
435
|
+
True
|
|
436
|
+
|
|
437
|
+
sage: Conic(RR, [1, 2, -3]).has_rational_point(point = True)
|
|
438
|
+
(True, (1.73205080756888 : 0.000000000000000 : 1.00000000000000))
|
|
439
|
+
|
|
440
|
+
Conics over polynomial rings can be solved internally::
|
|
441
|
+
|
|
442
|
+
sage: R.<t> = QQ[]
|
|
443
|
+
sage: C = Conic([-2, t^2 + 1, t^2 - 1])
|
|
444
|
+
sage: C.has_rational_point() # needs sage.libs.pari
|
|
445
|
+
True
|
|
446
|
+
|
|
447
|
+
And they can also be solved with Magma::
|
|
448
|
+
|
|
449
|
+
sage: C.has_rational_point(algorithm='magma') # optional - magma
|
|
450
|
+
True
|
|
451
|
+
sage: C.has_rational_point(algorithm='magma', point=True) # optional - magma
|
|
452
|
+
(True, (-t : 1 : 1))
|
|
453
|
+
|
|
454
|
+
sage: D = Conic([t, 1, t^2])
|
|
455
|
+
sage: D.has_rational_point(algorithm='magma') # optional - magma
|
|
456
|
+
False
|
|
457
|
+
|
|
458
|
+
TESTS:
|
|
459
|
+
|
|
460
|
+
One of the following fields comes with an embedding into the complex
|
|
461
|
+
numbers, one does not. Check that they are both handled correctly by
|
|
462
|
+
the Magma interface. ::
|
|
463
|
+
|
|
464
|
+
sage: # needs sage.rings.number_field
|
|
465
|
+
sage: K.<i> = QuadraticField(-1)
|
|
466
|
+
sage: K.coerce_embedding()
|
|
467
|
+
Generic morphism:
|
|
468
|
+
From: Number Field in i with defining polynomial x^2 + 1 with i = 1*I
|
|
469
|
+
To: Complex Lazy Field
|
|
470
|
+
Defn: i -> 1*I
|
|
471
|
+
sage: Conic(K, [1,1,1]).rational_point(algorithm='magma') # optional - magma
|
|
472
|
+
(-i : 1 : 0)
|
|
473
|
+
|
|
474
|
+
sage: # needs sage.rings.number_field
|
|
475
|
+
sage: x = QQ['x'].gen()
|
|
476
|
+
sage: L.<i> = NumberField(x^2 + 1, embedding=None)
|
|
477
|
+
sage: Conic(L, [1,1,1]).rational_point(algorithm='magma') # optional - magma
|
|
478
|
+
(-i : 1 : 0)
|
|
479
|
+
sage: L == K
|
|
480
|
+
False
|
|
481
|
+
"""
|
|
482
|
+
if read_cache:
|
|
483
|
+
if self._rational_point is not None:
|
|
484
|
+
if point:
|
|
485
|
+
return True, self._rational_point
|
|
486
|
+
else:
|
|
487
|
+
return True
|
|
488
|
+
|
|
489
|
+
B = self.base_ring()
|
|
490
|
+
|
|
491
|
+
if algorithm == 'magma':
|
|
492
|
+
from sage.interfaces.magma import magma
|
|
493
|
+
M = magma(self)
|
|
494
|
+
b = M.HasRationalPoint().sage()
|
|
495
|
+
if not point:
|
|
496
|
+
return b
|
|
497
|
+
if not b:
|
|
498
|
+
return False, None
|
|
499
|
+
M_pt = M.HasRationalPoint(nvals=2)[1]
|
|
500
|
+
|
|
501
|
+
# Various attempts will be made to convert `pt` to
|
|
502
|
+
# a Sage object. The end result will always be checked
|
|
503
|
+
# by self.point().
|
|
504
|
+
|
|
505
|
+
pt = [M_pt[1], M_pt[2], M_pt[3]]
|
|
506
|
+
|
|
507
|
+
# The first attempt is to use sequences. This is efficient and
|
|
508
|
+
# succeeds in cases where the Magma interface fails to convert
|
|
509
|
+
# number field elements, because embeddings between number fields
|
|
510
|
+
# may be lost on conversion to and from Magma.
|
|
511
|
+
# This should deal with all absolute number fields.
|
|
512
|
+
try:
|
|
513
|
+
return True, self.point([B(c.Eltseq().sage()) for c in pt])
|
|
514
|
+
except TypeError:
|
|
515
|
+
pass
|
|
516
|
+
|
|
517
|
+
# The second attempt tries to split Magma elements into
|
|
518
|
+
# numerators and denominators first. This is necessary
|
|
519
|
+
# for the field of rational functions, because (at the moment of
|
|
520
|
+
# writing) fraction field elements are not converted automatically
|
|
521
|
+
# from Magma to Sage.
|
|
522
|
+
try:
|
|
523
|
+
return True, self.point(
|
|
524
|
+
[B(c.Numerator().sage() / c.Denominator().sage()) for c in pt])
|
|
525
|
+
except (TypeError, NameError):
|
|
526
|
+
pass
|
|
527
|
+
|
|
528
|
+
# Finally, let the Magma interface handle conversion.
|
|
529
|
+
try:
|
|
530
|
+
return True, self.point([B(c.sage()) for c in pt])
|
|
531
|
+
except (TypeError, NameError):
|
|
532
|
+
pass
|
|
533
|
+
|
|
534
|
+
raise NotImplementedError("No correct conversion implemented for converting the Magma point %s on %s to a correct Sage point on self (=%s)" % (M_pt, M, self))
|
|
535
|
+
|
|
536
|
+
if algorithm != 'default':
|
|
537
|
+
raise ValueError("Unknown algorithm: %s" % algorithm)
|
|
538
|
+
|
|
539
|
+
if isinstance(B, sage.rings.abc.ComplexField):
|
|
540
|
+
if point:
|
|
541
|
+
_, _, _, d, e, f = self._coefficients
|
|
542
|
+
if d == 0:
|
|
543
|
+
return True, self.point([0, 1, 0])
|
|
544
|
+
return True, self.point([0, ((e**2-4*d*f).sqrt()-e)/(2*d), 1],
|
|
545
|
+
check=False)
|
|
546
|
+
return True
|
|
547
|
+
if isinstance(B, sage.rings.abc.RealField):
|
|
548
|
+
D, T = self.diagonal_matrix()
|
|
549
|
+
a, b, c = [D[0, 0], D[1, 1], D[2, 2]]
|
|
550
|
+
if a == 0:
|
|
551
|
+
ret = True, self.point(T*vector([1, 0, 0]), check=False)
|
|
552
|
+
elif a*c <= 0:
|
|
553
|
+
ret = True, self.point(T*vector([(-c/a).sqrt(), 0, 1]),
|
|
554
|
+
check=False)
|
|
555
|
+
elif b == 0:
|
|
556
|
+
ret = True, self.point(T*vector([0, 1, 0]), check=False)
|
|
557
|
+
elif b*c <= 0:
|
|
558
|
+
ret = True, self.point(T*vector([0, (-c/b).sqrt(), 0, 1]),
|
|
559
|
+
check=False)
|
|
560
|
+
else:
|
|
561
|
+
ret = False, None
|
|
562
|
+
if point:
|
|
563
|
+
return ret
|
|
564
|
+
return ret[0]
|
|
565
|
+
raise NotImplementedError("has_rational_point not implemented for "
|
|
566
|
+
"conics over base field %s" % B)
|
|
567
|
+
|
|
568
|
+
def has_singular_point(self, point=False):
|
|
569
|
+
r"""
|
|
570
|
+
Return ``True`` if and only if the conic ``self`` has a rational
|
|
571
|
+
singular point.
|
|
572
|
+
|
|
573
|
+
If ``point`` is ``True``, then also return a rational singular
|
|
574
|
+
point (or ``None`` if no such point exists).
|
|
575
|
+
|
|
576
|
+
EXAMPLES:
|
|
577
|
+
|
|
578
|
+
::
|
|
579
|
+
|
|
580
|
+
sage: c = Conic(QQ, [1,0,1]); c
|
|
581
|
+
Projective Conic Curve over Rational Field defined by x^2 + z^2
|
|
582
|
+
sage: c.has_singular_point(point = True)
|
|
583
|
+
(True, (0 : 1 : 0))
|
|
584
|
+
|
|
585
|
+
sage: P.<x,y,z> = GF(7)[]
|
|
586
|
+
sage: e = Conic((x+y+z)*(x-y+2*z)); e
|
|
587
|
+
Projective Conic Curve over Finite Field of size 7
|
|
588
|
+
defined by x^2 - y^2 + 3*x*z + y*z + 2*z^2
|
|
589
|
+
sage: e.has_singular_point(point = True)
|
|
590
|
+
(True, (2 : 4 : 1))
|
|
591
|
+
|
|
592
|
+
sage: Conic([1, 1, -1]).has_singular_point()
|
|
593
|
+
False
|
|
594
|
+
sage: Conic([1, 1, -1]).has_singular_point(point=True)
|
|
595
|
+
(False, None)
|
|
596
|
+
|
|
597
|
+
``has_singular_point`` is not implemented over all fields
|
|
598
|
+
of characteristic `2`. It is implemented over finite fields.
|
|
599
|
+
|
|
600
|
+
::
|
|
601
|
+
|
|
602
|
+
sage: F.<a> = FiniteField(8) # needs sage.rings.finite_rings
|
|
603
|
+
sage: Conic([a, a + 1, 1]).has_singular_point(point=True) # needs sage.rings.finite_rings
|
|
604
|
+
(True, (a + 1 : 0 : 1))
|
|
605
|
+
|
|
606
|
+
sage: P.<t> = GF(2)[]
|
|
607
|
+
sage: C = Conic(P, [t,t,1]); C
|
|
608
|
+
Projective Conic Curve over Fraction Field of Univariate Polynomial Ring
|
|
609
|
+
in t over Finite Field of size 2... defined by t*x^2 + t*y^2 + z^2
|
|
610
|
+
sage: C.has_singular_point(point=False)
|
|
611
|
+
Traceback (most recent call last):
|
|
612
|
+
...
|
|
613
|
+
NotImplementedError: Sorry, find singular point on conics not implemented
|
|
614
|
+
over all fields of characteristic 2.
|
|
615
|
+
"""
|
|
616
|
+
if not point:
|
|
617
|
+
ret = self.has_singular_point(point=True)
|
|
618
|
+
return ret[0]
|
|
619
|
+
B = self.base_ring()
|
|
620
|
+
if B.characteristic() == 2:
|
|
621
|
+
a, b, c, d, e, f = self.coefficients()
|
|
622
|
+
if b == 0 and c == 0 and e == 0:
|
|
623
|
+
for i in range(3):
|
|
624
|
+
if [a, d, f][i] == 0:
|
|
625
|
+
return True, self.point(vector(B, {2: 0, i: 1}))
|
|
626
|
+
if hasattr(a/f, 'is_square') and hasattr(a/f, 'sqrt'):
|
|
627
|
+
if (a/f).is_square():
|
|
628
|
+
return True, self.point([1, 0, (a/f).sqrt()])
|
|
629
|
+
if (d/f).is_square():
|
|
630
|
+
return True, self.point([0, 1, (d/f).sqrt()])
|
|
631
|
+
raise NotImplementedError("Sorry, find singular point on conics not implemented over all fields of characteristic 2.")
|
|
632
|
+
pt = [e, c, b]
|
|
633
|
+
if self.defining_polynomial()(pt) == 0:
|
|
634
|
+
return True, self.point(pt)
|
|
635
|
+
return False, None
|
|
636
|
+
D = self.symmetric_matrix()
|
|
637
|
+
if D.determinant() == 0:
|
|
638
|
+
return True, self.point(Sequence(D.right_kernel().gen()))
|
|
639
|
+
return False, None
|
|
640
|
+
|
|
641
|
+
def hom(self, x, Y=None):
|
|
642
|
+
r"""
|
|
643
|
+
Return the scheme morphism from ``self`` to ``Y`` defined by ``x``.
|
|
644
|
+
Here ``x`` can be a matrix or a sequence of polynomials.
|
|
645
|
+
If ``Y`` is omitted, then a natural image is found if possible.
|
|
646
|
+
|
|
647
|
+
EXAMPLES:
|
|
648
|
+
|
|
649
|
+
Here are a few morphisms given by matrices. In the first
|
|
650
|
+
example, ``Y`` is omitted, in the second example, ``Y`` is specified.
|
|
651
|
+
|
|
652
|
+
::
|
|
653
|
+
|
|
654
|
+
sage: c = Conic([-1, 1, 1])
|
|
655
|
+
sage: h = c.hom(Matrix([[1,1,0],[0,1,0],[0,0,1]])); h
|
|
656
|
+
Scheme morphism:
|
|
657
|
+
From: Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2
|
|
658
|
+
To: Projective Conic Curve over Rational Field defined by -x^2 + 2*x*y + z^2
|
|
659
|
+
Defn: Defined on coordinates by sending (x : y : z) to (x + y : y : z)
|
|
660
|
+
sage: h([-1, 1, 0]) # needs sage.libs.singular
|
|
661
|
+
(0 : 1 : 0)
|
|
662
|
+
|
|
663
|
+
sage: c = Conic([-1, 1, 1])
|
|
664
|
+
sage: d = Conic([4, 1, -1])
|
|
665
|
+
sage: c.hom(Matrix([[0, 0, 1/2], [0, 1, 0], [1, 0, 0]]), d)
|
|
666
|
+
Scheme morphism:
|
|
667
|
+
From: Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2
|
|
668
|
+
To: Projective Conic Curve over Rational Field defined by 4*x^2 + y^2 - z^2
|
|
669
|
+
Defn: Defined on coordinates by sending (x : y : z) to (1/2*z : y : x)
|
|
670
|
+
|
|
671
|
+
:exc:`ValueError` is raised if the wrong codomain ``Y`` is specified:
|
|
672
|
+
|
|
673
|
+
::
|
|
674
|
+
|
|
675
|
+
sage: c = Conic([-1, 1, 1])
|
|
676
|
+
sage: c.hom(Matrix([[0, 0, 1/2], [0, 1, 0], [1, 0, 0]]), c)
|
|
677
|
+
Traceback (most recent call last):
|
|
678
|
+
...
|
|
679
|
+
ValueError: The matrix x (= [ 0 0 1/2]
|
|
680
|
+
[ 0 1 0]
|
|
681
|
+
[ 1 0 0]) does not define a map
|
|
682
|
+
from self (= Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2)
|
|
683
|
+
to Y (= Projective Conic Curve over Rational Field defined by -x^2 + y^2 + z^2)
|
|
684
|
+
|
|
685
|
+
The identity map between two representations of the same conic:
|
|
686
|
+
|
|
687
|
+
::
|
|
688
|
+
|
|
689
|
+
sage: C = Conic([1,2,3,4,5,6])
|
|
690
|
+
sage: D = Conic([2,4,6,8,10,12])
|
|
691
|
+
sage: C.hom(identity_matrix(3), D)
|
|
692
|
+
Scheme morphism:
|
|
693
|
+
From: Projective Conic Curve over Rational Field
|
|
694
|
+
defined by x^2 + 2*x*y + 4*y^2 + 3*x*z + 5*y*z + 6*z^2
|
|
695
|
+
To: Projective Conic Curve over Rational Field
|
|
696
|
+
defined by 2*x^2 + 4*x*y + 8*y^2 + 6*x*z + 10*y*z + 12*z^2
|
|
697
|
+
Defn: Defined on coordinates by sending (x : y : z) to (x : y : z)
|
|
698
|
+
|
|
699
|
+
An example not over the rational numbers:
|
|
700
|
+
|
|
701
|
+
::
|
|
702
|
+
|
|
703
|
+
sage: P.<t> = QQ[]
|
|
704
|
+
sage: C = Conic([1,0,0,t,0,1/t])
|
|
705
|
+
sage: D = Conic([1/t^2, 0, -2/t^2, t, 0, (t + 1)/t^2])
|
|
706
|
+
sage: T = Matrix([[t,0,1], [0,1,0], [0,0,1]])
|
|
707
|
+
sage: C.hom(T, D)
|
|
708
|
+
Scheme morphism:
|
|
709
|
+
From: Projective Conic Curve over Fraction Field of Univariate
|
|
710
|
+
Polynomial Ring in t over Rational Field defined by x^2 + t*y^2 + 1/t*z^2
|
|
711
|
+
To: Projective Conic Curve over Fraction Field of Univariate
|
|
712
|
+
Polynomial Ring in t over Rational Field defined by
|
|
713
|
+
1/(t^2)*x^2 + t*y^2 - 2/(t^2)*x*z + (t + 1)/(t^2)*z^2
|
|
714
|
+
Defn: Defined on coordinates by sending (x : y : z) to (t*x + z : y : z)
|
|
715
|
+
"""
|
|
716
|
+
if isinstance(x, Matrix):
|
|
717
|
+
from .constructor import Conic
|
|
718
|
+
y = x.inverse()
|
|
719
|
+
A = y.transpose()*self.matrix()*y
|
|
720
|
+
im = Conic(A)
|
|
721
|
+
if Y is None:
|
|
722
|
+
Y = im
|
|
723
|
+
elif not Y == im:
|
|
724
|
+
raise ValueError("The matrix x (= %s) does not define a "
|
|
725
|
+
"map from self (= %s) to Y (= %s)" %
|
|
726
|
+
(x, self, Y))
|
|
727
|
+
x = Sequence(x*vector(self.ambient_space().gens()))
|
|
728
|
+
return self.Hom(Y)(x, check=False)
|
|
729
|
+
return super().hom(x, Y)
|
|
730
|
+
|
|
731
|
+
def is_diagonal(self):
|
|
732
|
+
r"""
|
|
733
|
+
Return ``True`` if and only if the conic has the form
|
|
734
|
+
`a x^2 + b y^2 + c z^2`.
|
|
735
|
+
|
|
736
|
+
EXAMPLES:
|
|
737
|
+
|
|
738
|
+
::
|
|
739
|
+
|
|
740
|
+
sage: c = Conic([1,1,0,1,0,1]); c
|
|
741
|
+
Projective Conic Curve over Rational Field defined by x^2 + x*y + y^2 + z^2
|
|
742
|
+
sage: d, t = c.diagonal_matrix()
|
|
743
|
+
sage: c.is_diagonal()
|
|
744
|
+
False
|
|
745
|
+
sage: c.diagonalization()[0].is_diagonal()
|
|
746
|
+
True
|
|
747
|
+
"""
|
|
748
|
+
return all(self.coefficients()[i] == 0 for i in [1, 2, 4])
|
|
749
|
+
|
|
750
|
+
def is_smooth(self):
|
|
751
|
+
r"""
|
|
752
|
+
Return ``True`` if and only if ``self`` is smooth.
|
|
753
|
+
|
|
754
|
+
EXAMPLES:
|
|
755
|
+
|
|
756
|
+
::
|
|
757
|
+
|
|
758
|
+
sage: Conic([1,-1,0]).is_smooth()
|
|
759
|
+
False
|
|
760
|
+
sage: Conic(GF(2),[1,1,1,1,1,0]).is_smooth()
|
|
761
|
+
True
|
|
762
|
+
"""
|
|
763
|
+
if self.base_ring().characteristic() == 2:
|
|
764
|
+
a, b, c, d, e, f = self.coefficients()
|
|
765
|
+
if b == 0 and c == 0 and e == 0:
|
|
766
|
+
return False
|
|
767
|
+
return self.defining_polynomial()([e, c, b]) != 0
|
|
768
|
+
return self.determinant() != 0
|
|
769
|
+
|
|
770
|
+
def _magma_init_(self, magma):
|
|
771
|
+
"""
|
|
772
|
+
Internal function. Returns a string to initialize this
|
|
773
|
+
conic in the Magma subsystem.
|
|
774
|
+
|
|
775
|
+
EXAMPLES::
|
|
776
|
+
|
|
777
|
+
sage: # optional - magma
|
|
778
|
+
sage: C = Conic(QQ, [1,2,3])
|
|
779
|
+
sage: C._magma_init_(magma)
|
|
780
|
+
'Conic([_sage_ref...|1/1,2/1,3/1,0/1,0/1,0/1])'
|
|
781
|
+
sage: C = Conic(GF(41), [-1,2,5])
|
|
782
|
+
sage: C._magma_init_(magma)
|
|
783
|
+
'Conic([_sage_ref...|GF(41)!40,GF(41)!2,GF(41)!5,GF(41)!0,GF(41)!0,GF(41)!0])'
|
|
784
|
+
sage: F.<a> = GF(25) # needs sage.rings.finite_rings
|
|
785
|
+
sage: C = Conic([3,0,1,4,a,2]); C # needs sage.rings.finite_rings
|
|
786
|
+
Projective Conic Curve over Finite Field in a of size 5^2
|
|
787
|
+
defined by -2*x^2 - y^2 + x*z + a*y*z + 2*z^2
|
|
788
|
+
sage: magma(C) # needs sage.rings.finite_rings
|
|
789
|
+
Conic over GF(5^2) defined by
|
|
790
|
+
3*X^2 + 4*Y^2 + X*Z + a*Y*Z + 2*Z^2
|
|
791
|
+
sage: magma(Conic([1/2,2/3,-4/5,6/7,8/9,-10/11]))
|
|
792
|
+
Conic over Rational Field defined by
|
|
793
|
+
1/2*X^2 + 2/3*X*Y + 6/7*Y^2 - 4/5*X*Z + 8/9*Y*Z - 10/11*Z^2
|
|
794
|
+
sage: R.<x> = Frac(QQ['x'])
|
|
795
|
+
sage: magma(Conic([x, 1 + x, 1 - x]))
|
|
796
|
+
Conic over Univariate rational function field over Rational Field defined by
|
|
797
|
+
x*X^2 + (x + 1)*Y^2 + (-x + 1)*Z^2
|
|
798
|
+
sage: P.<x> = QQ[]
|
|
799
|
+
sage: K.<b> = NumberField(x^3 + x + 1) # needs sage.rings.number_field
|
|
800
|
+
sage: magma(Conic([b,1,2])) # needs sage.rings.number_field
|
|
801
|
+
Conic over Number Field with defining polynomial x^3 + x + 1
|
|
802
|
+
over the Rational Field defined by b*X^2 + Y^2 + 2*Z^2
|
|
803
|
+
"""
|
|
804
|
+
kmn = magma(self.base_ring())._ref()
|
|
805
|
+
coeffs = self.coefficients()
|
|
806
|
+
magma_coeffs = [coeffs[i]._magma_init_(magma) for i in [0, 3, 5, 1, 4, 2]]
|
|
807
|
+
return 'Conic([%s|%s])' % (kmn, ','.join(magma_coeffs))
|
|
808
|
+
|
|
809
|
+
def matrix(self):
|
|
810
|
+
r"""
|
|
811
|
+
Return a matrix `M` such that `(x, y, z) M (x, y, z)^t`
|
|
812
|
+
is the defining equation of ``self``.
|
|
813
|
+
|
|
814
|
+
The matrix `M` is upper triangular if the base field has
|
|
815
|
+
characteristic `2` and symmetric otherwise.
|
|
816
|
+
|
|
817
|
+
EXAMPLES::
|
|
818
|
+
|
|
819
|
+
sage: R.<x, y, z> = QQ[]
|
|
820
|
+
sage: C = Conic(x^2 + x*y + y^2 + z^2)
|
|
821
|
+
sage: C.matrix()
|
|
822
|
+
[ 1 1/2 0]
|
|
823
|
+
[1/2 1 0]
|
|
824
|
+
[ 0 0 1]
|
|
825
|
+
|
|
826
|
+
sage: R.<x, y, z> = GF(2)[]
|
|
827
|
+
sage: C = Conic(x^2 + x*y + y^2 + x*z + z^2)
|
|
828
|
+
sage: C.matrix()
|
|
829
|
+
[1 1 1]
|
|
830
|
+
[0 1 0]
|
|
831
|
+
[0 0 1]
|
|
832
|
+
"""
|
|
833
|
+
if self.base_ring().characteristic() == 2:
|
|
834
|
+
return self.upper_triangular_matrix()
|
|
835
|
+
return self.symmetric_matrix()
|
|
836
|
+
|
|
837
|
+
_matrix_ = matrix
|
|
838
|
+
|
|
839
|
+
def parametrization(self, point=None, morphism=True):
|
|
840
|
+
r"""
|
|
841
|
+
Return a parametrization `f` of ``self`` together with the
|
|
842
|
+
inverse of `f`.
|
|
843
|
+
|
|
844
|
+
If ``point`` is specified, then that point is used
|
|
845
|
+
for the parametrization. Otherwise, use :meth:`rational_point()`
|
|
846
|
+
to find a point.
|
|
847
|
+
|
|
848
|
+
If ``morphism`` is True, then `f` is returned in the form
|
|
849
|
+
of a Scheme morphism. Otherwise, it is a tuple of polynomials
|
|
850
|
+
that gives the parametrization.
|
|
851
|
+
|
|
852
|
+
EXAMPLES:
|
|
853
|
+
|
|
854
|
+
An example over a finite field ::
|
|
855
|
+
|
|
856
|
+
sage: # needs sage.libs.pari
|
|
857
|
+
sage: c = Conic(GF(2), [1,1,1,1,1,0])
|
|
858
|
+
sage: f, g = c.parametrization(); f, g
|
|
859
|
+
(Scheme morphism:
|
|
860
|
+
From: Projective Space of dimension 1 over Finite Field of size 2
|
|
861
|
+
To: Projective Conic Curve over Finite Field of size 2
|
|
862
|
+
defined by x^2 + x*y + y^2 + x*z + y*z
|
|
863
|
+
Defn: Defined on coordinates by sending (x : y) to ...,
|
|
864
|
+
Scheme morphism:
|
|
865
|
+
From: Projective Conic Curve over Finite Field of size 2
|
|
866
|
+
defined by x^2 + x*y + y^2 + x*z + y*z
|
|
867
|
+
To: Projective Space of dimension 1 over Finite Field of size 2
|
|
868
|
+
Defn: Defined on coordinates by sending (x : y : z) to ...)
|
|
869
|
+
sage: set(f(p) for p in f.domain())
|
|
870
|
+
{(0 : 0 : 1), (0 : 1 : 1), (1 : 0 : 1)}
|
|
871
|
+
|
|
872
|
+
Verification of the example ::
|
|
873
|
+
|
|
874
|
+
sage: # needs sage.libs.pari
|
|
875
|
+
sage: h = g*f; h
|
|
876
|
+
Scheme endomorphism of Projective Space of dimension 1
|
|
877
|
+
over Finite Field of size 2
|
|
878
|
+
Defn: Defined on coordinates by sending (x : y) to ...
|
|
879
|
+
sage: h[0]/h[1]
|
|
880
|
+
x/y
|
|
881
|
+
sage: h.is_one() # known bug (see :issue:`31892`)
|
|
882
|
+
True
|
|
883
|
+
sage: (x,y,z) = c.gens()
|
|
884
|
+
sage: x.parent()
|
|
885
|
+
Quotient of Multivariate Polynomial Ring in x, y, z
|
|
886
|
+
over Finite Field of size 2 by the ideal (x^2 + x*y + y^2 + x*z + y*z)
|
|
887
|
+
sage: k = f*g
|
|
888
|
+
sage: k[0]*z-k[2]*x
|
|
889
|
+
0
|
|
890
|
+
sage: k[1]*z-k[2]*y
|
|
891
|
+
0
|
|
892
|
+
|
|
893
|
+
The morphisms are mathematically defined in all points,
|
|
894
|
+
but don't work completely in SageMath (see :issue:`31892`) ::
|
|
895
|
+
|
|
896
|
+
sage: # needs sage.libs.pari
|
|
897
|
+
sage: f, g = c.parametrization([0,0,1])
|
|
898
|
+
sage: g([0,1,1])
|
|
899
|
+
(1 : 0)
|
|
900
|
+
sage: f([1,0])
|
|
901
|
+
(0 : 1 : 1)
|
|
902
|
+
sage: f([1,1])
|
|
903
|
+
(0 : 0 : 1)
|
|
904
|
+
sage: g([0,0,1])
|
|
905
|
+
(1 : 1)
|
|
906
|
+
|
|
907
|
+
An example with ``morphism = False`` ::
|
|
908
|
+
|
|
909
|
+
sage: # needs sage.libs.pari
|
|
910
|
+
sage: R.<x,y,z> = QQ[]
|
|
911
|
+
sage: C = Curve(7*x^2 + 2*y*z + z^2)
|
|
912
|
+
sage: (p, i) = C.parametrization(morphism=False); (p, i)
|
|
913
|
+
([-2*x*y, x^2 + 7*y^2, -2*x^2], [-1/2*x, 1/7*y + 1/14*z])
|
|
914
|
+
sage: C.defining_polynomial()(p)
|
|
915
|
+
0
|
|
916
|
+
sage: i[0](p) / i[1](p)
|
|
917
|
+
x/y
|
|
918
|
+
|
|
919
|
+
A :exc:`ValueError` is raised if ``self`` has no rational point ::
|
|
920
|
+
|
|
921
|
+
sage: # needs sage.libs.pari
|
|
922
|
+
sage: C = Conic(x^2 + y^2 + 7*z^2)
|
|
923
|
+
sage: C.parametrization()
|
|
924
|
+
Traceback (most recent call last):
|
|
925
|
+
...
|
|
926
|
+
ValueError: Conic Projective Conic Curve over Rational Field defined by
|
|
927
|
+
x^2 + y^2 + 7*z^2 has no rational points over Rational Field!
|
|
928
|
+
|
|
929
|
+
A :exc:`ValueError` is raised if ``self`` is not smooth ::
|
|
930
|
+
|
|
931
|
+
sage: # needs sage.libs.pari
|
|
932
|
+
sage: C = Conic(x^2 + y^2)
|
|
933
|
+
sage: C.parametrization()
|
|
934
|
+
Traceback (most recent call last):
|
|
935
|
+
...
|
|
936
|
+
ValueError: The conic self (=Projective Conic Curve over Rational Field
|
|
937
|
+
defined by x^2 + y^2) is not smooth, hence does not have a parametrization.
|
|
938
|
+
"""
|
|
939
|
+
if (self._parametrization is not None) and not point:
|
|
940
|
+
par = self._parametrization
|
|
941
|
+
else:
|
|
942
|
+
if not self.is_smooth():
|
|
943
|
+
raise ValueError("The conic self (=%s) is not smooth, hence does not have a parametrization." % self)
|
|
944
|
+
if point is None:
|
|
945
|
+
point = self.rational_point()
|
|
946
|
+
point = Sequence(point)
|
|
947
|
+
B = self.base_ring()
|
|
948
|
+
Q = PolynomialRing(B, 'x,y')
|
|
949
|
+
x, y = Q.gens()
|
|
950
|
+
gens = self.ambient_space().gens()
|
|
951
|
+
P = PolynomialRing(B, 4, ['X', 'Y', 'T0', 'T1'])
|
|
952
|
+
X, Y, T0, T1 = P.gens()
|
|
953
|
+
c3 = next(j for j in range(2, -1, -1) if point[j] != 0)
|
|
954
|
+
c1 = next(j for j in range(3) if j != c3)
|
|
955
|
+
c2 = next(j for j in range(3) if j != c3 and j != c1)
|
|
956
|
+
L = [0, 0, 0]
|
|
957
|
+
L[c1] = Y * T1 * point[c1] + Y * T0
|
|
958
|
+
L[c2] = Y * T1 * point[c2] + X * T0
|
|
959
|
+
L[c3] = Y * T1 * point[c3]
|
|
960
|
+
bezout = P(self.defining_polynomial()(L) / T0)
|
|
961
|
+
t = [bezout([x, y, 0, -1]), bezout([x, y, 1, 0])]
|
|
962
|
+
par = (tuple([Q(p([x, y, t[0], t[1]]) / y) for p in L]),
|
|
963
|
+
tuple([gens[m] * point[c3] - gens[c3] * point[m]
|
|
964
|
+
for m in [c2, c1]]))
|
|
965
|
+
if self._parametrization is None:
|
|
966
|
+
self._parametrization = par
|
|
967
|
+
if not morphism:
|
|
968
|
+
return par
|
|
969
|
+
P1 = ProjectiveSpace(self.base_ring(), 1, 'x,y')
|
|
970
|
+
return P1.hom(par[0], self), self.Hom(P1)(par[1], check=False)
|
|
971
|
+
|
|
972
|
+
def point(self, v, check=True):
|
|
973
|
+
r"""
|
|
974
|
+
Construct a point on ``self`` corresponding to the input ``v``.
|
|
975
|
+
|
|
976
|
+
If ``check`` is True, then checks if ``v`` defines a valid
|
|
977
|
+
point on ``self``.
|
|
978
|
+
|
|
979
|
+
If no rational point on ``self`` is known yet, then also caches the point
|
|
980
|
+
for use by :meth:`rational_point` and :meth:`parametrization`.
|
|
981
|
+
|
|
982
|
+
EXAMPLES::
|
|
983
|
+
|
|
984
|
+
sage: c = Conic([1, -1, 1])
|
|
985
|
+
sage: c.point([15, 17, 8])
|
|
986
|
+
(15/8 : 17/8 : 1)
|
|
987
|
+
sage: c.rational_point()
|
|
988
|
+
(15/8 : 17/8 : 1)
|
|
989
|
+
sage: d = Conic([1, -1, 1])
|
|
990
|
+
sage: d.rational_point() # needs sage.libs.pari
|
|
991
|
+
(-1 : 1 : 0)
|
|
992
|
+
"""
|
|
993
|
+
if isinstance(v, Vector):
|
|
994
|
+
v = Sequence(v)
|
|
995
|
+
p = super().point(v, check=check)
|
|
996
|
+
if self._rational_point is None:
|
|
997
|
+
self._rational_point = p
|
|
998
|
+
return p
|
|
999
|
+
|
|
1000
|
+
def random_rational_point(self, *args1, **args2):
|
|
1001
|
+
r"""
|
|
1002
|
+
Return a random rational point of the conic ``self``.
|
|
1003
|
+
|
|
1004
|
+
ALGORITHM:
|
|
1005
|
+
|
|
1006
|
+
1. Compute a parametrization `f` of ``self`` using :meth:`parametrization`.
|
|
1007
|
+
2. Computes a random point `(x:y)` on the projective line.
|
|
1008
|
+
3. Output `f(x:y)`.
|
|
1009
|
+
|
|
1010
|
+
The coordinates `x` and `y` are computed using
|
|
1011
|
+
``B.random_element``, where ``B`` is the base field of
|
|
1012
|
+
``self`` and additional arguments to ``random_rational_point``
|
|
1013
|
+
are passed to ``random_element``.
|
|
1014
|
+
|
|
1015
|
+
If the base field is a finite field, then the
|
|
1016
|
+
output is uniformly distributed over the points of ``self``.
|
|
1017
|
+
|
|
1018
|
+
EXAMPLES::
|
|
1019
|
+
|
|
1020
|
+
sage: # needs sage.libs.pari
|
|
1021
|
+
sage: c = Conic(GF(2), [1,1,1,1,1,0])
|
|
1022
|
+
sage: [c.random_rational_point() for i in range(10)] # random
|
|
1023
|
+
[(1 : 0 : 1), (1 : 0 : 1), (1 : 0 : 1), (0 : 1 : 1), (1 : 0 : 1),
|
|
1024
|
+
(0 : 0 : 1), (1 : 0 : 1), (1 : 0 : 1), (0 : 0 : 1), (1 : 0 : 1)]
|
|
1025
|
+
sage: d = Conic(QQ, [1, 1, -1])
|
|
1026
|
+
sage: d.random_rational_point(den_bound=1, num_bound=5) # random
|
|
1027
|
+
(-24/25 : 7/25 : 1)
|
|
1028
|
+
sage: Conic(QQ, [1, 1, 1]).random_rational_point()
|
|
1029
|
+
Traceback (most recent call last):
|
|
1030
|
+
...
|
|
1031
|
+
ValueError: Conic Projective Conic Curve over Rational Field defined by
|
|
1032
|
+
x^2 + y^2 + z^2 has no rational points over Rational Field!
|
|
1033
|
+
"""
|
|
1034
|
+
if not self.is_smooth():
|
|
1035
|
+
raise NotImplementedError("Sorry, random points not implemented "
|
|
1036
|
+
"for non-smooth conics")
|
|
1037
|
+
par = self.parametrization()
|
|
1038
|
+
x = 0
|
|
1039
|
+
y = 0
|
|
1040
|
+
B = self.base_ring()
|
|
1041
|
+
while x == 0 and y == 0:
|
|
1042
|
+
x = B.random_element(*args1, **args2)
|
|
1043
|
+
y = B.random_element(*args1, **args2)
|
|
1044
|
+
return par[0]([x, y])
|
|
1045
|
+
|
|
1046
|
+
def rational_point(self, algorithm='default', read_cache=True):
|
|
1047
|
+
r"""
|
|
1048
|
+
Return a point on ``self`` defined over the base field.
|
|
1049
|
+
|
|
1050
|
+
This raises a :exc:`ValueError` if no rational point exists.
|
|
1051
|
+
|
|
1052
|
+
See ``self.has_rational_point`` for the algorithm used
|
|
1053
|
+
and for the use of the parameters ``algorithm`` and ``read_cache``.
|
|
1054
|
+
|
|
1055
|
+
EXAMPLES:
|
|
1056
|
+
|
|
1057
|
+
Examples over `\QQ` ::
|
|
1058
|
+
|
|
1059
|
+
sage: R.<x,y,z> = QQ[]
|
|
1060
|
+
|
|
1061
|
+
sage: # needs sage.libs.pari
|
|
1062
|
+
sage: C = Conic(7*x^2 + 2*y*z + z^2)
|
|
1063
|
+
sage: C.rational_point()
|
|
1064
|
+
(0 : 1 : 0)
|
|
1065
|
+
sage: C = Conic(x^2 + 2*y^2 + z^2)
|
|
1066
|
+
sage: C.rational_point()
|
|
1067
|
+
Traceback (most recent call last):
|
|
1068
|
+
...
|
|
1069
|
+
ValueError: Conic Projective Conic Curve over Rational Field defined by
|
|
1070
|
+
x^2 + 2*y^2 + z^2 has no rational points over Rational Field!
|
|
1071
|
+
|
|
1072
|
+
sage: C = Conic(x^2 + y^2 + 7*z^2)
|
|
1073
|
+
sage: C.rational_point(algorithm='rnfisnorm')
|
|
1074
|
+
Traceback (most recent call last):
|
|
1075
|
+
...
|
|
1076
|
+
ValueError: Conic Projective Conic Curve over Rational Field defined by
|
|
1077
|
+
x^2 + y^2 + 7*z^2 has no rational points over Rational Field!
|
|
1078
|
+
|
|
1079
|
+
Examples over number fields ::
|
|
1080
|
+
|
|
1081
|
+
sage: # needs sage.rings.number_field
|
|
1082
|
+
sage: P.<x> = QQ[]
|
|
1083
|
+
sage: L.<b> = NumberField(x^3 - 5)
|
|
1084
|
+
sage: C = Conic(L, [3, 2, -b])
|
|
1085
|
+
sage: p = C.rational_point(algorithm='rnfisnorm')
|
|
1086
|
+
sage: p # output is random
|
|
1087
|
+
(1/3*b^2 - 4/3*b + 4/3 : b^2 - 2 : 1)
|
|
1088
|
+
sage: C.defining_polynomial()(list(p))
|
|
1089
|
+
0
|
|
1090
|
+
|
|
1091
|
+
sage: K.<i> = QuadraticField(-1) # needs sage.rings.number_field
|
|
1092
|
+
sage: D = Conic(K, [3, 2, 5]) # needs sage.rings.number_field
|
|
1093
|
+
sage: D.rational_point(algorithm='rnfisnorm') # output is random # needs sage.rings.number_field
|
|
1094
|
+
(-3 : 4*i : 1)
|
|
1095
|
+
|
|
1096
|
+
sage: # needs sage.libs.pari sage.rings.number_field
|
|
1097
|
+
sage: L.<s> = QuadraticField(2)
|
|
1098
|
+
sage: Conic(QQ, [1, 1, -3]).has_rational_point()
|
|
1099
|
+
False
|
|
1100
|
+
sage: E = Conic(L, [1, 1, -3])
|
|
1101
|
+
sage: E.rational_point() # output is random
|
|
1102
|
+
(-1 : -s : 1)
|
|
1103
|
+
|
|
1104
|
+
Currently Magma is better at solving conics over number fields than
|
|
1105
|
+
Sage, so it helps to use the algorithm 'magma' if Magma is installed::
|
|
1106
|
+
|
|
1107
|
+
sage: # optional - magma, needs sage.rings.number_field
|
|
1108
|
+
sage: q = C.rational_point(algorithm='magma',
|
|
1109
|
+
....: read_cache=False)
|
|
1110
|
+
sage: q # output is random
|
|
1111
|
+
(1/5*b^2 : 1/5*b^2 : 1)
|
|
1112
|
+
sage: C.defining_polynomial()(list(q))
|
|
1113
|
+
0
|
|
1114
|
+
sage: len(str(p)) > 1.5*len(str(q))
|
|
1115
|
+
True
|
|
1116
|
+
sage: D.rational_point(algorithm='magma', # random
|
|
1117
|
+
....: read_cache=False)
|
|
1118
|
+
(1 : 2*i : 1)
|
|
1119
|
+
sage: E.rational_point(algorithm='magma', # random
|
|
1120
|
+
....: read_cache=False)
|
|
1121
|
+
(-s : 1 : 1)
|
|
1122
|
+
|
|
1123
|
+
sage: # needs sage.libs.pari sage.rings.number_field
|
|
1124
|
+
sage: F = Conic([L.gen(), 30, -20])
|
|
1125
|
+
sage: q = F.rational_point(algorithm='magma') # optional - magma
|
|
1126
|
+
sage: q # random # optional - magma
|
|
1127
|
+
(-10/7*s + 40/7 : 5/7*s - 6/7 : 1)
|
|
1128
|
+
sage: p = F.rational_point(read_cache=False)
|
|
1129
|
+
sage: p # random
|
|
1130
|
+
(788210*s - 1114700 : -171135*s + 242022 : 1)
|
|
1131
|
+
sage: len(str(p)) > len(str(q)) # optional - magma
|
|
1132
|
+
True
|
|
1133
|
+
|
|
1134
|
+
sage: # needs sage.rings.number_field
|
|
1135
|
+
sage: G = Conic([L.gen(), 30, -21])
|
|
1136
|
+
sage: G.has_rational_point(algorithm='magma') # optional - magma
|
|
1137
|
+
False
|
|
1138
|
+
sage: G.has_rational_point(read_cache=False) # needs sage.libs.pari
|
|
1139
|
+
False
|
|
1140
|
+
sage: G.has_rational_point(algorithm='local',
|
|
1141
|
+
....: read_cache=False)
|
|
1142
|
+
False
|
|
1143
|
+
sage: G.rational_point(algorithm='magma') # optional - magma
|
|
1144
|
+
Traceback (most recent call last):
|
|
1145
|
+
...
|
|
1146
|
+
ValueError: Conic Projective Conic Curve over Number Field in s
|
|
1147
|
+
with defining polynomial x^2 - 2 with s = 1.414213562373095?
|
|
1148
|
+
defined by s*x^2 + 30*y^2 - 21*z^2 has no rational points over
|
|
1149
|
+
Number Field in s with defining polynomial x^2 - 2 with s = 1.414213562373095?!
|
|
1150
|
+
sage: G.rational_point(algorithm='magma', # optional - magma
|
|
1151
|
+
....: read_cache=False)
|
|
1152
|
+
Traceback (most recent call last):
|
|
1153
|
+
...
|
|
1154
|
+
ValueError: Conic Projective Conic Curve over Number Field in s
|
|
1155
|
+
with defining polynomial x^2 - 2 with s = 1.414213562373095?
|
|
1156
|
+
defined by s*x^2 + 30*y^2 - 21*z^2 has no rational points over
|
|
1157
|
+
Number Field in s with defining polynomial x^2 - 2 with s = 1.414213562373095?!
|
|
1158
|
+
|
|
1159
|
+
Examples over finite fields ::
|
|
1160
|
+
|
|
1161
|
+
sage: F.<a> = FiniteField(7^20) # needs sage.rings.finite_rings
|
|
1162
|
+
sage: C = Conic([1, a, -5]); C # needs sage.rings.finite_rings
|
|
1163
|
+
Projective Conic Curve over Finite Field in a of size 7^20
|
|
1164
|
+
defined by x^2 + a*y^2 + 2*z^2
|
|
1165
|
+
sage: C.rational_point() # output is random # needs sage.rings.finite_rings
|
|
1166
|
+
(4*a^19 + 5*a^18 + 4*a^17 + a^16 + 6*a^15 + 3*a^13 + 6*a^11 + a^9
|
|
1167
|
+
+ 3*a^8 + 2*a^7 + 4*a^6 + 3*a^5 + 3*a^4 + a^3 + a + 6
|
|
1168
|
+
: 5*a^18 + a^17 + a^16 + 6*a^15 + 4*a^14 + a^13 + 5*a^12 + 5*a^10
|
|
1169
|
+
+ 2*a^9 + 6*a^8 + 6*a^7 + 6*a^6 + 2*a^4 + 3
|
|
1170
|
+
: 1)
|
|
1171
|
+
|
|
1172
|
+
Examples over `\RR` and `\CC` ::
|
|
1173
|
+
|
|
1174
|
+
sage: Conic(CC, [1, 2, 3]).rational_point()
|
|
1175
|
+
(0 : 1.22474487139159*I : 1)
|
|
1176
|
+
|
|
1177
|
+
sage: Conic(RR, [1, 1, 1]).rational_point()
|
|
1178
|
+
Traceback (most recent call last):
|
|
1179
|
+
...
|
|
1180
|
+
ValueError: Conic Projective Conic Curve over Real Field
|
|
1181
|
+
with 53 bits of precision defined by x^2 + y^2 + z^2 has
|
|
1182
|
+
no rational points over Real Field with 53 bits of precision!
|
|
1183
|
+
"""
|
|
1184
|
+
bl, pt = self.has_rational_point(point=True, algorithm=algorithm,
|
|
1185
|
+
read_cache=read_cache)
|
|
1186
|
+
if bl:
|
|
1187
|
+
return pt
|
|
1188
|
+
raise ValueError("Conic %s has no rational points over %s!" %
|
|
1189
|
+
(self, self.ambient_space().base_ring()))
|
|
1190
|
+
|
|
1191
|
+
def singular_point(self):
|
|
1192
|
+
r"""
|
|
1193
|
+
Return a singular rational point of ``self``.
|
|
1194
|
+
|
|
1195
|
+
EXAMPLES:
|
|
1196
|
+
|
|
1197
|
+
::
|
|
1198
|
+
|
|
1199
|
+
sage: Conic(GF(2), [1,1,1,1,1,1]).singular_point()
|
|
1200
|
+
(1 : 1 : 1)
|
|
1201
|
+
|
|
1202
|
+
:exc:`ValueError` is raised if the conic has no rational
|
|
1203
|
+
singular point
|
|
1204
|
+
|
|
1205
|
+
::
|
|
1206
|
+
|
|
1207
|
+
sage: Conic(QQ, [1,1,1,1,1,1]).singular_point()
|
|
1208
|
+
Traceback (most recent call last):
|
|
1209
|
+
...
|
|
1210
|
+
ValueError: The conic self (= Projective Conic Curve over Rational Field
|
|
1211
|
+
defined by x^2 + x*y + y^2 + x*z + y*z + z^2) has no rational singular point
|
|
1212
|
+
"""
|
|
1213
|
+
b = self.has_singular_point(point=True)
|
|
1214
|
+
if not b[0]:
|
|
1215
|
+
raise ValueError("The conic self (= %s) has no rational "
|
|
1216
|
+
"singular point" % self)
|
|
1217
|
+
return b[1]
|
|
1218
|
+
|
|
1219
|
+
def symmetric_matrix(self):
|
|
1220
|
+
r"""
|
|
1221
|
+
The symmetric matrix `M` such that `(x y z) M (x y z)^t`
|
|
1222
|
+
is the defining equation of ``self``.
|
|
1223
|
+
|
|
1224
|
+
EXAMPLES::
|
|
1225
|
+
|
|
1226
|
+
sage: R.<x, y, z> = QQ[]
|
|
1227
|
+
sage: C = Conic(x^2 + x*y/2 + y^2 + z^2)
|
|
1228
|
+
sage: C.symmetric_matrix()
|
|
1229
|
+
[ 1 1/4 0]
|
|
1230
|
+
[1/4 1 0]
|
|
1231
|
+
[ 0 0 1]
|
|
1232
|
+
|
|
1233
|
+
sage: C = Conic(x^2 + 2*x*y + y^2 + 3*x*z + z^2)
|
|
1234
|
+
sage: v = vector([x, y, z])
|
|
1235
|
+
sage: v * C.symmetric_matrix() * v
|
|
1236
|
+
x^2 + 2*x*y + y^2 + 3*x*z + z^2
|
|
1237
|
+
"""
|
|
1238
|
+
a, b, c, d, e, f = self.coefficients()
|
|
1239
|
+
if self.base_ring().characteristic() == 2:
|
|
1240
|
+
if b == 0 and c == 0 and e == 0:
|
|
1241
|
+
return matrix([[a, 0, 0], [0, d, 0], [0, 0, f]])
|
|
1242
|
+
raise ValueError("The conic self (= %s) has no symmetric matrix "
|
|
1243
|
+
"because the base field has characteristic 2" %
|
|
1244
|
+
self)
|
|
1245
|
+
return matrix([[a, b / 2, c / 2],
|
|
1246
|
+
[b / 2, d, e / 2],
|
|
1247
|
+
[c / 2, e / 2, f]])
|
|
1248
|
+
|
|
1249
|
+
def upper_triangular_matrix(self):
|
|
1250
|
+
r"""
|
|
1251
|
+
The upper-triangular matrix `M` such that `(x y z) M (x y z)^t`
|
|
1252
|
+
is the defining equation of ``self``.
|
|
1253
|
+
|
|
1254
|
+
EXAMPLES::
|
|
1255
|
+
|
|
1256
|
+
sage: R.<x, y, z> = QQ[]
|
|
1257
|
+
sage: C = Conic(x^2 + x*y + y^2 + z^2)
|
|
1258
|
+
sage: C.upper_triangular_matrix()
|
|
1259
|
+
[1 1 0]
|
|
1260
|
+
[0 1 0]
|
|
1261
|
+
[0 0 1]
|
|
1262
|
+
|
|
1263
|
+
sage: C = Conic(x^2 + 2*x*y + y^2 + 3*x*z + z^2)
|
|
1264
|
+
sage: v = vector([x, y, z])
|
|
1265
|
+
sage: v * C.upper_triangular_matrix() * v
|
|
1266
|
+
x^2 + 2*x*y + y^2 + 3*x*z + z^2
|
|
1267
|
+
"""
|
|
1268
|
+
from sage.matrix.constructor import matrix
|
|
1269
|
+
a, b, c, d, e, f = self.coefficients()
|
|
1270
|
+
return matrix([[a, b, c],
|
|
1271
|
+
[0, d, e],
|
|
1272
|
+
[0, 0, f]])
|
|
1273
|
+
|
|
1274
|
+
def variable_names(self):
|
|
1275
|
+
r"""
|
|
1276
|
+
Return the variable names of the defining polynomial of ``self``.
|
|
1277
|
+
|
|
1278
|
+
EXAMPLES:
|
|
1279
|
+
|
|
1280
|
+
::
|
|
1281
|
+
|
|
1282
|
+
sage: c = Conic([1,1,0,1,0,1], 'x,y,z')
|
|
1283
|
+
sage: c.variable_names()
|
|
1284
|
+
('x', 'y', 'z')
|
|
1285
|
+
sage: c.variable_name()
|
|
1286
|
+
'x'
|
|
1287
|
+
|
|
1288
|
+
The function ``variable_names()`` is required
|
|
1289
|
+
for the following construction:
|
|
1290
|
+
|
|
1291
|
+
::
|
|
1292
|
+
|
|
1293
|
+
sage: C.<p,q,r> = Conic(QQ, [1, 1, 1]); C # needs sage.libs.singular
|
|
1294
|
+
Projective Conic Curve over Rational Field defined by p^2 + q^2 + r^2
|
|
1295
|
+
"""
|
|
1296
|
+
return self.defining_polynomial().parent().variable_names()
|