passagemath-schemes 10.6.47__cp312-cp312-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.
Files changed (311) hide show
  1. passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
  2. passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
  4. passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
  5. passagemath_schemes/__init__.py +3 -0
  6. passagemath_schemes-10.6.47.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.47.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.47.dist-info/RECORD +311 -0
  9. passagemath_schemes-10.6.47.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.47.dist-info/top_level.txt +3 -0
  11. sage/all__sagemath_schemes.py +23 -0
  12. sage/databases/all__sagemath_schemes.py +7 -0
  13. sage/databases/cremona.py +1723 -0
  14. sage/dynamics/all__sagemath_schemes.py +2 -0
  15. sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
  16. sage/dynamics/arithmetic_dynamics/all.py +14 -0
  17. sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
  18. sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
  19. sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
  20. sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
  21. sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
  22. sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
  23. sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-312-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +745 -0
  29. sage/lfunctions/pari.py +818 -0
  30. sage/lfunctions/zero_sums.cpython-312-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5135 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
  34. sage/modular/abvar/abvar_newform.py +244 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +186 -0
  37. sage/modular/abvar/cuspidal_subgroup.py +371 -0
  38. sage/modular/abvar/finite_subgroup.py +896 -0
  39. sage/modular/abvar/homology.py +720 -0
  40. sage/modular/abvar/homspace.py +998 -0
  41. sage/modular/abvar/lseries.py +415 -0
  42. sage/modular/abvar/morphism.py +935 -0
  43. sage/modular/abvar/torsion_point.py +274 -0
  44. sage/modular/abvar/torsion_subgroup.py +740 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-312-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1402 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-312-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +363 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +653 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1469 -0
  57. sage/modular/arithgroup/congroup_generic.py +628 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +267 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-312-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1066 -0
  61. sage/modular/arithgroup/tests.py +418 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3753 -0
  64. sage/modular/btquotients/pautomorphicform.py +2570 -0
  65. sage/modular/buzzard.py +100 -0
  66. sage/modular/congroup.py +29 -0
  67. sage/modular/congroup_element.py +13 -0
  68. sage/modular/cusps.py +1109 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +569 -0
  71. sage/modular/dirichlet.py +3310 -0
  72. sage/modular/drinfeld_modform/all.py +2 -0
  73. sage/modular/drinfeld_modform/element.py +446 -0
  74. sage/modular/drinfeld_modform/ring.py +773 -0
  75. sage/modular/drinfeld_modform/tutorial.py +236 -0
  76. sage/modular/etaproducts.py +1065 -0
  77. sage/modular/hecke/algebra.py +746 -0
  78. sage/modular/hecke/all.py +20 -0
  79. sage/modular/hecke/ambient_module.py +1019 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +325 -0
  82. sage/modular/hecke/hecke_operator.py +780 -0
  83. sage/modular/hecke/homspace.py +206 -0
  84. sage/modular/hecke/module.py +1767 -0
  85. sage/modular/hecke/morphism.py +174 -0
  86. sage/modular/hecke/submodule.py +989 -0
  87. sage/modular/hypergeometric_misc.cpython-312-darwin.so +0 -0
  88. sage/modular/hypergeometric_misc.pxd +4 -0
  89. sage/modular/hypergeometric_misc.pyx +166 -0
  90. sage/modular/hypergeometric_motive.py +2017 -0
  91. sage/modular/local_comp/all.py +2 -0
  92. sage/modular/local_comp/liftings.py +292 -0
  93. sage/modular/local_comp/local_comp.py +1071 -0
  94. sage/modular/local_comp/smoothchar.py +1825 -0
  95. sage/modular/local_comp/type_space.py +748 -0
  96. sage/modular/modform/all.py +30 -0
  97. sage/modular/modform/ambient.py +815 -0
  98. sage/modular/modform/ambient_R.py +177 -0
  99. sage/modular/modform/ambient_eps.py +306 -0
  100. sage/modular/modform/ambient_g0.py +124 -0
  101. sage/modular/modform/ambient_g1.py +204 -0
  102. sage/modular/modform/constructor.py +545 -0
  103. sage/modular/modform/cuspidal_submodule.py +708 -0
  104. sage/modular/modform/defaults.py +14 -0
  105. sage/modular/modform/eis_series.py +505 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4131 -0
  108. sage/modular/modform/find_generators.py +59 -0
  109. sage/modular/modform/half_integral.py +154 -0
  110. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  111. sage/modular/modform/j_invariant.py +47 -0
  112. sage/modular/modform/l_series_gross_zagier.py +133 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-312-darwin.so +0 -0
  114. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  115. sage/modular/modform/notes.py +45 -0
  116. sage/modular/modform/numerical.py +514 -0
  117. sage/modular/modform/periods.py +14 -0
  118. sage/modular/modform/ring.py +1257 -0
  119. sage/modular/modform/space.py +1860 -0
  120. sage/modular/modform/submodule.py +118 -0
  121. sage/modular/modform/tests.py +64 -0
  122. sage/modular/modform/theta.py +110 -0
  123. sage/modular/modform/vm_basis.py +381 -0
  124. sage/modular/modform/weight1.py +220 -0
  125. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  126. sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
  127. sage/modular/modform_hecketriangle/all.py +30 -0
  128. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  129. sage/modular/modform_hecketriangle/constructor.py +416 -0
  130. sage/modular/modform_hecketriangle/element.py +351 -0
  131. sage/modular/modform_hecketriangle/functors.py +752 -0
  132. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  133. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
  135. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
  136. sage/modular/modform_hecketriangle/readme.py +1214 -0
  137. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  138. sage/modular/modform_hecketriangle/space.py +1037 -0
  139. sage/modular/modform_hecketriangle/subspace.py +423 -0
  140. sage/modular/modsym/all.py +17 -0
  141. sage/modular/modsym/ambient.py +3846 -0
  142. sage/modular/modsym/boundary.py +1420 -0
  143. sage/modular/modsym/element.py +336 -0
  144. sage/modular/modsym/g1list.py +178 -0
  145. sage/modular/modsym/ghlist.py +182 -0
  146. sage/modular/modsym/hecke_operator.py +73 -0
  147. sage/modular/modsym/manin_symbol.cpython-312-darwin.so +0 -0
  148. sage/modular/modsym/manin_symbol.pxd +5 -0
  149. sage/modular/modsym/manin_symbol.pyx +497 -0
  150. sage/modular/modsym/manin_symbol_list.py +1295 -0
  151. sage/modular/modsym/modsym.py +400 -0
  152. sage/modular/modsym/modular_symbols.py +384 -0
  153. sage/modular/modsym/p1list_nf.py +1241 -0
  154. sage/modular/modsym/relation_matrix.py +591 -0
  155. sage/modular/modsym/relation_matrix_pyx.cpython-312-darwin.so +0 -0
  156. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  157. sage/modular/modsym/space.py +2468 -0
  158. sage/modular/modsym/subspace.py +455 -0
  159. sage/modular/modsym/tests.py +375 -0
  160. sage/modular/multiple_zeta.py +2632 -0
  161. sage/modular/multiple_zeta_F_algebra.py +786 -0
  162. sage/modular/overconvergent/all.py +6 -0
  163. sage/modular/overconvergent/genus0.py +1878 -0
  164. sage/modular/overconvergent/hecke_series.py +1187 -0
  165. sage/modular/overconvergent/weightspace.py +778 -0
  166. sage/modular/pollack_stevens/all.py +4 -0
  167. sage/modular/pollack_stevens/distributions.py +874 -0
  168. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  169. sage/modular/pollack_stevens/manin_map.py +859 -0
  170. sage/modular/pollack_stevens/modsym.py +1593 -0
  171. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  172. sage/modular/pollack_stevens/sigma0.py +534 -0
  173. sage/modular/pollack_stevens/space.py +1076 -0
  174. sage/modular/quasimodform/all.py +3 -0
  175. sage/modular/quasimodform/element.py +845 -0
  176. sage/modular/quasimodform/ring.py +828 -0
  177. sage/modular/quatalg/all.py +3 -0
  178. sage/modular/quatalg/brandt.py +1642 -0
  179. sage/modular/ssmod/all.py +8 -0
  180. sage/modular/ssmod/ssmod.py +827 -0
  181. sage/rings/all__sagemath_schemes.py +1 -0
  182. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  183. sage/rings/polynomial/binary_form_reduce.py +585 -0
  184. sage/schemes/all.py +41 -0
  185. sage/schemes/berkovich/all.py +6 -0
  186. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  187. sage/schemes/berkovich/berkovich_space.py +748 -0
  188. sage/schemes/curves/affine_curve.py +2928 -0
  189. sage/schemes/curves/all.py +33 -0
  190. sage/schemes/curves/closed_point.py +434 -0
  191. sage/schemes/curves/constructor.py +381 -0
  192. sage/schemes/curves/curve.py +542 -0
  193. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  194. sage/schemes/curves/point.py +463 -0
  195. sage/schemes/curves/projective_curve.py +3026 -0
  196. sage/schemes/curves/zariski_vankampen.py +1932 -0
  197. sage/schemes/cyclic_covers/all.py +2 -0
  198. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  199. sage/schemes/cyclic_covers/constructor.py +137 -0
  200. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  201. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  202. sage/schemes/elliptic_curves/BSD.py +1036 -0
  203. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  204. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  205. sage/schemes/elliptic_curves/all.py +49 -0
  206. sage/schemes/elliptic_curves/cardinality.py +609 -0
  207. sage/schemes/elliptic_curves/cm.py +1102 -0
  208. sage/schemes/elliptic_curves/constructor.py +1552 -0
  209. sage/schemes/elliptic_curves/ec_database.py +175 -0
  210. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  211. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  212. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  213. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  214. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  215. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  216. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  217. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  218. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  219. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  220. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  221. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  222. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  223. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  224. sage/schemes/elliptic_curves/formal_group.py +760 -0
  225. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  226. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  227. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  228. sage/schemes/elliptic_curves/heegner.py +7335 -0
  229. sage/schemes/elliptic_curves/height.py +2109 -0
  230. sage/schemes/elliptic_curves/hom.py +1406 -0
  231. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  232. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  233. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  234. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  235. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  236. sage/schemes/elliptic_curves/homset.py +271 -0
  237. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  238. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  239. sage/schemes/elliptic_curves/jacobian.py +237 -0
  240. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  241. sage/schemes/elliptic_curves/kraus.py +1014 -0
  242. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  243. sage/schemes/elliptic_curves/mod5family.py +105 -0
  244. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  245. sage/schemes/elliptic_curves/mod_sym_num.cpython-312-darwin.so +0 -0
  246. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  247. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  248. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  249. sage/schemes/elliptic_curves/padics.py +1816 -0
  250. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  251. sage/schemes/elliptic_curves/period_lattice_region.cpython-312-darwin.so +0 -0
  252. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  253. sage/schemes/elliptic_curves/saturation.py +715 -0
  254. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  255. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  256. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  257. sage/schemes/hyperelliptic_curves/all.py +6 -0
  258. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  259. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  260. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  261. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  264. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  265. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  266. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  267. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  270. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  271. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  272. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  273. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  274. sage/schemes/jacobians/all.py +2 -0
  275. sage/schemes/overview.py +161 -0
  276. sage/schemes/plane_conics/all.py +22 -0
  277. sage/schemes/plane_conics/con_field.py +1296 -0
  278. sage/schemes/plane_conics/con_finite_field.py +158 -0
  279. sage/schemes/plane_conics/con_number_field.py +456 -0
  280. sage/schemes/plane_conics/con_rational_field.py +406 -0
  281. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  282. sage/schemes/plane_conics/constructor.py +249 -0
  283. sage/schemes/plane_quartics/all.py +2 -0
  284. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  285. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  286. sage/schemes/riemann_surfaces/all.py +1 -0
  287. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  288. sage_wheels/share/cremona/cremona_mini.db +0 -0
  289. sage_wheels/share/ellcurves/rank0 +30427 -0
  290. sage_wheels/share/ellcurves/rank1 +31871 -0
  291. sage_wheels/share/ellcurves/rank10 +6 -0
  292. sage_wheels/share/ellcurves/rank11 +6 -0
  293. sage_wheels/share/ellcurves/rank12 +1 -0
  294. sage_wheels/share/ellcurves/rank14 +1 -0
  295. sage_wheels/share/ellcurves/rank15 +1 -0
  296. sage_wheels/share/ellcurves/rank17 +1 -0
  297. sage_wheels/share/ellcurves/rank19 +1 -0
  298. sage_wheels/share/ellcurves/rank2 +2388 -0
  299. sage_wheels/share/ellcurves/rank20 +1 -0
  300. sage_wheels/share/ellcurves/rank21 +1 -0
  301. sage_wheels/share/ellcurves/rank22 +1 -0
  302. sage_wheels/share/ellcurves/rank23 +1 -0
  303. sage_wheels/share/ellcurves/rank24 +1 -0
  304. sage_wheels/share/ellcurves/rank28 +1 -0
  305. sage_wheels/share/ellcurves/rank3 +836 -0
  306. sage_wheels/share/ellcurves/rank4 +10 -0
  307. sage_wheels/share/ellcurves/rank5 +5 -0
  308. sage_wheels/share/ellcurves/rank6 +5 -0
  309. sage_wheels/share/ellcurves/rank7 +5 -0
  310. sage_wheels/share/ellcurves/rank8 +6 -0
  311. 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()