@@ -4753,9 +4753,8 @@ def _S_class_group_quotient_matrix(self, S):
4753
4753
assert A [:c ] == 1 and A [c :] == 0
4754
4754
return Q [:c , :a ]
4755
4755
4756
- def selmer_group (self , S , m , proof = True , orders = False ):
4757
- r"""
4758
- Compute the group `K(S,m)`.
4756
+ def selmer_generators (self , S , m , proof = True , orders = False ):
4757
+ r"""Compute generators of the group `K(S,m)`.
4759
4758
4760
4759
INPUT:
4761
4760
@@ -4791,14 +4790,23 @@ def selmer_group(self, S, m, proof=True, orders=False):
4791
4790
outside of `S`, but may contain it properly when not all
4792
4791
primes dividing `m` are in `S`.
4793
4792
4793
+ .. NOTE::
4794
+
4795
+ When `m=p` is prime, see also the method
4796
+ :meth:`NumberField_generic.selmer_space` which gives
4797
+ additional output: as well as generators, it gives an
4798
+ abstract vector space over `\F_p` isomorphic to `K(S,p)`
4799
+ and maps implementing the isomorphism between this space
4800
+ and `K(S,p)` as a subgroup of `K^*/(K^*)^p`.
4801
+
4794
4802
EXAMPLES::
4795
4803
4796
4804
sage: K.<a> = QuadraticField(-5)
4797
- sage: K.selmer_group ((), 2)
4805
+ sage: K.selmer_generators ((), 2)
4798
4806
[-1, 2]
4799
4807
4800
4808
The previous example shows that the group generated by the
4801
- output may be strictly larger than the 'true' Selmer group of
4809
+ output may be strictly larger than the group of
4802
4810
elements giving extensions unramified outside `S`, since that
4803
4811
has order just 2, generated by `-1`::
4804
4812
@@ -4812,31 +4820,31 @@ def selmer_group(self, S, m, proof=True, orders=False):
4812
4820
sage: K.<a> = QuadraticField(-5)
4813
4821
sage: P2 = K.ideal(2, -a+1)
4814
4822
sage: P3 = K.ideal(3, a+1)
4815
- sage: K.selmer_group ((), 2, orders=True)
4823
+ sage: K.selmer_generators ((), 2, orders=True)
4816
4824
([-1, 2], [2, 2])
4817
- sage: K.selmer_group ((), 4, orders=True)
4825
+ sage: K.selmer_generators ((), 4, orders=True)
4818
4826
([-1, 4], [2, 2])
4819
- sage: K.selmer_group ([P2], 2)
4827
+ sage: K.selmer_generators ([P2], 2)
4820
4828
[2, -1]
4821
- sage: K.selmer_group ((P2,P3), 4)
4829
+ sage: K.selmer_generators ((P2,P3), 4)
4822
4830
[2, -a - 1, -1]
4823
- sage: K.selmer_group ((P2,P3), 4, orders=True)
4831
+ sage: K.selmer_generators ((P2,P3), 4, orders=True)
4824
4832
([2, -a - 1, -1], [4, 4, 2])
4825
- sage: K.selmer_group ([P2], 3)
4833
+ sage: K.selmer_generators ([P2], 3)
4826
4834
[2]
4827
- sage: K.selmer_group ([P2, P3], 3)
4835
+ sage: K.selmer_generators ([P2, P3], 3)
4828
4836
[2, -a - 1]
4829
- sage: K.selmer_group ([P2, P3, K.ideal(a)], 3) # random signs
4837
+ sage: K.selmer_generators ([P2, P3, K.ideal(a)], 3) # random signs
4830
4838
[2, a + 1, a]
4831
4839
4832
4840
Example over `\QQ` (as a number field)::
4833
4841
4834
4842
sage: K.<a> = NumberField(polygen(QQ))
4835
- sage: K.selmer_group ([],5)
4843
+ sage: K.selmer_generators ([],5)
4836
4844
[]
4837
- sage: K.selmer_group ([K.prime_above(p) for p in [2,3,5]],2)
4845
+ sage: K.selmer_generators ([K.prime_above(p) for p in [2,3,5]],2)
4838
4846
[2, 3, 5, -1]
4839
- sage: K.selmer_group ([K.prime_above(p) for p in [2,3,5]],6, orders=True)
4847
+ sage: K.selmer_generators ([K.prime_above(p) for p in [2,3,5]],6, orders=True)
4840
4848
([2, 3, 5, -1], [6, 6, 6, 2])
4841
4849
4842
4850
TESTS::
@@ -4845,15 +4853,15 @@ def selmer_group(self, S, m, proof=True, orders=False):
4845
4853
sage: P2 = K.ideal(2, -a+1)
4846
4854
sage: P3 = K.ideal(3, a+1)
4847
4855
sage: P5 = K.ideal(a)
4848
- sage: S = K.selmer_group ([P2, P3, P5], 3)
4856
+ sage: S = K.selmer_generators ([P2, P3, P5], 3)
4849
4857
sage: S in ([2, a + 1, a], [2, a + 1, -a], [2, -a - 1, a], [2, -a - 1, -a]) or S
4850
4858
True
4851
4859
4852
4860
Verify that :trac:`14489` is fixed;
4853
4861
the representation depends on the PARI version::
4854
4862
4855
4863
sage: K.<a> = NumberField(x^3 - 381 * x + 127)
4856
- sage: gens = K.selmer_group (K.primes_above(13), 2)
4864
+ sage: gens = K.selmer_generators (K.primes_above(13), 2)
4857
4865
sage: len(gens) == 8
4858
4866
True
4859
4867
sage: gens[:5]
@@ -4873,9 +4881,10 @@ def selmer_group(self, S, m, proof=True, orders=False):
4873
4881
4874
4882
sage: K.<a> = QuadraticField(-5)
4875
4883
sage: p = K.primes_above(2)[0]
4876
- sage: S = K.selmer_group ((), 4)
4884
+ sage: S = K.selmer_generators ((), 4)
4877
4885
sage: all(4.divides(x.valuation(p)) for x in S)
4878
4886
True
4887
+
4879
4888
"""
4880
4889
units , clgp_gens = self ._S_class_group_and_units (tuple (S ), proof = proof )
4881
4890
gens = []
@@ -4921,6 +4930,9 @@ def selmer_group(self, S, m, proof=True, orders=False):
4921
4930
else :
4922
4931
return gens
4923
4932
4933
+ # For backwards compatibility:
4934
+ selmer_group = selmer_generators
4935
+
4924
4936
def selmer_group_iterator (self , S , m , proof = True ):
4925
4937
r"""
4926
4938
Return an iterator through elements of the finite group `K(S,m)`.
@@ -4936,7 +4948,7 @@ def selmer_group_iterator(self, S, m, proof=True):
4936
4948
OUTPUT:
4937
4949
4938
4950
An iterator yielding the distinct elements of `K(S,m)`. See
4939
- the docstring for :meth:`NumberField_generic.selmer_group ` for
4951
+ the docstring for :meth:`NumberField_generic.selmer_generators ` for
4940
4952
more information.
4941
4953
4942
4954
EXAMPLES::
@@ -4961,12 +4973,116 @@ def selmer_group_iterator(self, S, m, proof=True):
4961
4973
sage: list(K.selmer_group_iterator([K.prime_above(p) for p in [11,13]],2))
4962
4974
[1, -1, 13, -13, 11, -11, 143, -143]
4963
4975
"""
4964
- KSgens , ords = self .selmer_group (S = S , m = m , proof = proof , orders = True )
4976
+ KSgens , ords = self .selmer_generators (S = S , m = m , proof = proof , orders = True )
4965
4977
one = self .one ()
4966
4978
from sage .misc .all import cartesian_product_iterator
4967
4979
for ev in cartesian_product_iterator ([range (o ) for o in ords ]):
4968
4980
yield prod ([p ** e for p , e in zip (KSgens , ev )], one )
4969
4981
4982
+ def selmer_space (self , S , p , proof = None ):
4983
+ r"""Compute the group `K(S,p)` as a vector space with maps to and from `K^*`.
4984
+
4985
+ INPUT:
4986
+
4987
+ - ``S`` -- a set of primes ideals of ``self``
4988
+
4989
+ - ``p`` -- a prime number
4990
+
4991
+ - ``proof`` -- if False, assume the GRH in computing the class group
4992
+
4993
+ OUTPUT:
4994
+
4995
+ (tuple) ``KSp``, ``KSp_gens``, ``from_KSp``, ``to_KSp`` where
4996
+
4997
+ - ``KSp`` is an abstract vector space over `GF(p)` isomorphic to `K(S,p)`;
4998
+
4999
+ - ``KSp_gens`` is a list of elements of `K^*` generating `K(S,p)`;
5000
+
5001
+ - ``from_KSp`` is a function from ``KSp`` to `K^*`
5002
+ implementing the isomorphism from the abstract `K(S,p)` to
5003
+ `K(S,p)` as a subgroup of `K^*/(K^*)^p`;
5004
+
5005
+ - ``to_KSP`` is a partial function from `K^*` to ``KSp``,
5006
+ defined on elements `a` whose image in `K^*/(K^*)^p` lies in
5007
+ `K(S,p)`, mapping them via the inverse isomorphism to the
5008
+ abstract vector space ``KSp``.
5009
+
5010
+ The group `K(S,p)` is the finite subgroup of `K^*/(K^*)^p$
5011
+ consisting of elements whose valuation at all orimes not in
5012
+ `S` is a multiple of `p`. It contains the subgroup of those
5013
+ `a\in K^*` such that `K(\sqrt[p]{a})/K` is unramified at all
5014
+ primes of `K` outside of `S`, but may contain it properly when
5015
+ not all primes dividing `p` are in `S`.
5016
+
5017
+ EXAMPLES:
5018
+
5019
+ A real quadratic field with class number 2, where the fundamental
5020
+ unit is a generator, and the class group provides another
5021
+ generator when `p==2`::
5022
+
5023
+ sage: K.<a> = QuadraticField(-5)
5024
+ sage: K.class_number()
5025
+ 2
5026
+ sage: P2 = K.ideal(2, -a+1)
5027
+ sage: P3 = K.ideal(3, a+1)
5028
+ sage: P5 = K.ideal(a)
5029
+ sage: KS2, gens, fromKS2, toKS2 = K.selmer_space([P2, P3, P5], 2)
5030
+ sage: KS2
5031
+ Vector space of dimension 4 over Finite Field of size 2
5032
+ sage: gens
5033
+ [a + 1, a, 2, -1]
5034
+
5035
+ Each generator must have even valuation at primes not in `S`::
5036
+
5037
+ sage: [K.ideal(g).factor() for g in gens]
5038
+ [(Fractional ideal (2, a + 1)) * (Fractional ideal (3, a + 1)),
5039
+ Fractional ideal (-a),
5040
+ (Fractional ideal (2, a + 1))^2,
5041
+ 1]
5042
+
5043
+ sage: toKS2(10)
5044
+ (0, 0, 1, 1)
5045
+ sage: fromKS2([0,0,1,1])
5046
+ -2
5047
+ sage: K(10/(-2)).is_square()
5048
+ True
5049
+
5050
+ sage: KS3, gens, fromKS3, toKS3 = K.selmer_space([P2, P3, P5], 3)
5051
+ sage: KS3
5052
+ Vector space of dimension 3 over Finite Field of size 3
5053
+ sage: gens
5054
+ [1/2, 1/4*a + 1/4, a]
5055
+
5056
+ An example to show that the group 'K(S,2)` may be strictly
5057
+ larger than the group of elements giving extensions unramified
5058
+ outside `S`. In this case, with `K` of class number `2` and
5059
+ `S` empty, there is only one quadratic extension of `K`
5060
+ unramified outside `S`, the Hilbert Class Field
5061
+ `K(\sqrt{-1})`::
5062
+
5063
+ sage: K.<a> = QuadraticField(-5)
5064
+ sage: KS2, gens, fromKS2, toKS2 = K.selmer_space([], 2)
5065
+ sage: KS2
5066
+ Vector space of dimension 2 over Finite Field of size 2
5067
+ sage: gens
5068
+ [2, -1]
5069
+ sage: for v in KS2:
5070
+ ....: if not v:
5071
+ ....: continue
5072
+ ....: a = fromKS2(v)
5073
+ ....: print((a,K.extension(x^2-a, 'roota').relative_discriminant().factor()))
5074
+ ....:
5075
+ (2, (Fractional ideal (2, a + 1))^4)
5076
+ (-1, 1)
5077
+ (-2, (Fractional ideal (2, a + 1))^4)
5078
+
5079
+ sage: K.hilbert_class_field('b')
5080
+ Number Field in b with defining polynomial x^2 + 1 over its base field
5081
+
5082
+ """
5083
+ from sage .rings .number_field .selmer_group import pSelmerGroup
5084
+ return pSelmerGroup (self , S , p , proof )
5085
+
4970
5086
def composite_fields (self , other , names = None , both_maps = False , preserve_embedding = True ):
4971
5087
"""
4972
5088
Return the possible composite number fields formed from
@@ -5493,7 +5609,7 @@ def elements_of_norm(self, n, proof=None):
5493
5609
- ``n`` -- integer in this number field
5494
5610
5495
5611
- ``proof`` -- boolean (default: ``True``, unless you called
5496
- ``number_field_proof` ` and set it otherwise)
5612
+ :meth:`proof.number_field ` and set it otherwise)
5497
5613
5498
5614
OUTPUT:
5499
5615
@@ -6904,6 +7020,7 @@ def S_unit_group(self, proof=None, S=None):
6904
7020
INPUT:
6905
7021
6906
7022
- ``proof`` (bool, default True) flag passed to ``pari``.
7023
+
6907
7024
- ``S`` - list or tuple of prime ideals, or an ideal, or a single
6908
7025
ideal or element from which an ideal can be constructed, in
6909
7026
which case the support is used. If None, the global unit
@@ -11657,12 +11774,15 @@ def is_galois(self):
11657
11774
return True
11658
11775
11659
11776
def class_number (self , proof = None ):
11660
- r"""
11661
- Return the size of the class group of self.
11777
+ r"""Return the size of the class group of self.
11778
+
11779
+ INPUT:
11662
11780
11663
- If proof = False (*not* the default!) and the discriminant of the
11664
- field is negative, then the following warning from the PARI manual
11665
- applies:
11781
+ - ``proof`` -- boolean (default: ``True``, unless you called
11782
+ :meth:`proof.number_field` and set it otherwise). If
11783
+ ``proof`` is ``False`` (*not* the default!), and the
11784
+ discriminant of the field is negative, then the following
11785
+ warning from the PARI manual applies:
11666
11786
11667
11787
.. warning::
11668
11788
@@ -11701,6 +11821,7 @@ def class_number(self, proof=None):
11701
11821
<type 'sage.rings.integer.Integer'>
11702
11822
sage: type(CyclotomicField(10).class_number())
11703
11823
<type 'sage.rings.integer.Integer'>
11824
+
11704
11825
"""
11705
11826
proof = proof_flag (proof )
11706
11827
try :
0 commit comments