Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download
Views: 184633
1
#################################################################################
2
#
3
# (c) Copyright 2011 William Stein
4
#
5
# This file is part of PSAGE
6
#
7
# PSAGE is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# PSAGE is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#
20
#################################################################################
21
22
"""
23
Fast prime ideals of the ring R of integers of Q(sqrt(5)).
24
25
This module implements Cython classes for prime ideals of R, and their
26
enumeration. The main entry function is primes_of_bounded_norm::
27
28
sage: from psage.number_fields.sqrt5 import primes_of_bounded_norm
29
sage: v = primes_of_bounded_norm(50); v
30
[2, 5a, 3, 11a, 11b, 19a, 19b, 29a, 29b, 31a, 31b, 41a, 41b, 7]
31
32
Note that the output of primes_of_bounded_norm is a list. Each entry
33
is a prime ideal, which prints using a simple label consisting of the
34
characteristic of the prime then "a" or "b", where "b" only appears for
35
the second split prime.::
36
37
sage: type(v[8])
38
<type 'psage.number_fields.sqrt5.prime.Prime'>
39
sage: v[8].sage_ideal()
40
Fractional ideal (a + 5)
41
42
AUTHOR:
43
- William Stein
44
"""
45
46
47
#include "stdsage.pxi"
48
#include "interrupt.pxi"
49
50
from cpython.object cimport Py_TYPE, PyTypeObject
51
52
53
cdef inline PY_NEW(type t):
54
"""
55
Return ``t.__new__(t)``. This works even for types like
56
:class:`Integer` where we change ``tp_new`` at runtime (Cython
57
optimizations assume that ``tp_new`` doesn't change).
58
"""
59
return (<PyTypeObject*>t).tp_new(t, <object>NULL, <object>NULL)
60
61
62
cdef inline void PY_SET_TP_NEW(type dst, type src):
63
"""
64
Manually set ``dst.__new__`` to ``src.__new__``. This is used to
65
speed up Cython's boilerplate object construction code by skipping
66
irrelevant base class ``tp_new`` methods.
67
"""
68
(<PyTypeObject*>dst).tp_new = (<PyTypeObject*>src).tp_new
69
70
71
cdef inline bint HAS_DICTIONARY(obj):
72
"""
73
Test whether the given object has a Python dictionary.
74
"""
75
return Py_TYPE(obj).tp_dictoffset != 0
76
77
cdef extern from "pari/pari.h":
78
unsigned long Fl_sqrt(unsigned long, unsigned long)
79
unsigned long Fl_div(unsigned long, unsigned long, unsigned long)
80
81
from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal
82
83
cdef class Prime:
84
"""
85
Nonzero prime ideal of the ring of integers of Q(sqrt(5)). This
86
is a fast customized Cython class; to get at the corresponding
87
Sage prime ideal use the sage_ideal method.
88
"""
89
# cdef public long p, r
90
# cdef bint first
91
# cpdef long norm(self)
92
# cpdef bint is_split(self)
93
# cpdef bint is_inert(self)
94
# cpdef bint is_ramified(self)
95
def __init__(self, p, long r=0, bint first=True):
96
"""
97
Create Prime ideal with given residue characteristic, root,
98
and first or not with that characterstic.
99
100
INPUT form 1:
101
- `p` -- prime
102
- `r` -- root (or 0)
103
- ``first`` -- boolean: True if first prime over p
104
105
INPUT form 2:
106
- p -- prime ideal of integers of Q(sqrt(5)); validity of the
107
input is not checked in any way!
108
109
NOTE: No checking is done to verify that the input is valid.
110
111
EXAMPLES::
112
113
sage: from psage.number_fields.sqrt5.prime import Prime
114
sage: P = Prime(2,0,True); P
115
2
116
sage: type(P)
117
<type 'psage.number_fields.sqrt5.prime.Prime'>
118
sage: P = Prime(5,3,True); P
119
5a
120
sage: P = Prime(11,8,True); P
121
11a
122
sage: P = Prime(11,4,False); P
123
11b
124
125
We can also set P using a prime ideal of the ring of integers::
126
127
sage: from psage.number_fields.sqrt5.prime import Prime; K.<a> = NumberField(x^2-x-1)
128
sage: P1 = Prime(K.primes_above(11)[0]); P2 = Prime(K.primes_above(11)[1]); P1, P2
129
(11b, 11a)
130
sage: P1 > P2
131
True
132
sage: Prime(K.prime_above(2))
133
2
134
sage: P = Prime(K.prime_above(5)); P, P.r
135
(5a, 3)
136
sage: Prime(K.prime_above(3))
137
3
138
139
Test that conversion both ways works for primes up to norm `10^5`::
140
141
sage: from psage.number_fields.sqrt5.prime import primes_of_bounded_norm, Prime
142
sage: v = primes_of_bounded_norm(10^5)
143
sage: w = [Prime(z.sage_ideal()) for z in v]
144
sage: v == w
145
True
146
"""
147
cdef long t, r1
148
if isinstance(p, NumberFieldFractionalIdeal):
149
# Set self using a prime ideal of Q(sqrt(5)).
150
H = p.pari_hnf()
151
self.p = H[0,0]
152
self.first = True
153
t = self.p % 5
154
if t == 1 or t == 4:
155
self.r = self.p - H[0,1]
156
r1 = self.p + 1 - self.r
157
if self.r > r1:
158
self.first = False
159
elif t == 0:
160
self.r = 3
161
else:
162
self.r = 0
163
else:
164
self.p = p
165
self.r = r
166
self.first = first
167
168
def __repr__(self):
169
"""
170
EXAMPLES::
171
172
sage: from psage.number_fields.sqrt5.prime import Prime
173
sage: Prime(11,4,False).__repr__()
174
'11b'
175
sage: Prime(11,4,True).__repr__()
176
'11a'
177
sage: Prime(7,0,True).__repr__()
178
'7'
179
"""
180
if self.r:
181
return '%s%s'%(self.p, 'a' if self.first else 'b')
182
return '%s'%self.p
183
184
def __hash__(self):
185
return self.p*(self.r+1) + int(self.first)
186
187
def _latex_(self):
188
"""
189
EXAMPLES::
190
191
sage: from psage.number_fields.sqrt5.prime import Prime
192
sage: Prime(11,8,True)._latex_()
193
'11a'
194
sage: Prime(11,4,False)._latex_()
195
'11b'
196
"""
197
return self.__repr__()
198
199
cpdef bint is_split(self):
200
"""
201
Return True if this prime is split (and not ramified).
202
203
EXAMPLES::
204
205
sage: from psage.number_fields.sqrt5.prime import Prime
206
sage: Prime(11,8,True).is_split()
207
True
208
sage: Prime(3,0,True).is_split()
209
False
210
sage: Prime(5,3,True).is_split()
211
False
212
"""
213
return self.r != 0 and self.p != 5
214
215
cpdef bint is_inert(self):
216
"""
217
Return True if this prime is inert.
218
219
EXAMPLES::
220
221
sage: from psage.number_fields.sqrt5.prime import Prime
222
sage: Prime(11,8,True).is_inert()
223
False
224
sage: Prime(3,0,True).is_inert()
225
True
226
sage: Prime(5,3,True).is_inert()
227
False
228
"""
229
return self.r == 0
230
231
cpdef bint is_ramified(self):
232
"""
233
Return True if this prime is ramified (i.e., the prime over 5).
234
235
EXAMPLES::
236
237
sage: from psage.number_fields.sqrt5.prime import Prime
238
sage: Prime(11,8,True).is_ramified()
239
False
240
sage: Prime(3,0,True).is_ramified()
241
False
242
sage: Prime(5,3,True).is_ramified()
243
True
244
"""
245
return self.p == 5
246
247
cpdef long norm(self):
248
"""
249
Return the norm of this ideal.
250
251
EXAMPLES::
252
253
sage: from psage.number_fields.sqrt5.prime import Prime
254
sage: Prime(11,4,True).norm()
255
11
256
sage: Prime(7,0,True).norm()
257
49
258
"""
259
return self.p if self.r else self.p*self.p
260
261
def __cmp__(self, Prime right):
262
"""
263
Compare two prime ideals. First sort by the norm, then in the
264
(only remaining) split case if the norms are the same, compare
265
the residue of (1+sqrt(5))/2 in the interval [0,p).
266
267
WARNING: The ordering is NOT the same as the ordering of
268
fractional ideals in Sage.
269
270
EXAMPLES::
271
272
sage: from psage.number_fields.sqrt5 import primes_of_bounded_norm
273
sage: v = primes_of_bounded_norm(50); v
274
[2, 5a, 3, 11a, 11b, 19a, 19b, 29a, 29b, 31a, 31b, 41a, 41b, 7]
275
sage: v[3], v[4]
276
(11a, 11b)
277
sage: v[3] < v[4]
278
True
279
sage: v[4] > v[3]
280
True
281
282
We test the ordering a bit by sorting::
283
284
sage: v.sort(); v
285
[2, 5a, 3, 11a, 11b, 19a, 19b, 29a, 29b, 31a, 31b, 41a, 41b, 7]
286
sage: v = list(reversed(v)); v
287
[7, 41b, 41a, 31b, 31a, 29b, 29a, 19b, 19a, 11b, 11a, 3, 5a, 2]
288
sage: v.sort(); v
289
[2, 5a, 3, 11a, 11b, 19a, 19b, 29a, 29b, 31a, 31b, 41a, 41b, 7]
290
291
A bigger test::
292
293
sage: v = primes_of_bounded_norm(10^7)
294
sage: w = list(reversed(v)); w.sort()
295
sage: v == w
296
True
297
"""
298
cdef long selfn = self.norm(), rightn = right.norm()
299
if selfn > rightn: return 1
300
elif rightn > selfn: return -1
301
elif self.r > right.r: return 1
302
elif right.r > self.r: return -1
303
else: return 0
304
305
def sage_ideal(self):
306
"""
307
Return the usual prime fractional ideal associated to this
308
prime. This is slow, but provides substantial additional
309
functionality.
310
311
EXAMPLES::
312
313
sage: from psage.number_fields.sqrt5 import primes_of_bounded_norm
314
sage: v = primes_of_bounded_norm(20)
315
sage: v[1].sage_ideal()
316
Fractional ideal (2*a - 1)
317
sage: [P.sage_ideal() for P in v]
318
[Fractional ideal (2), Fractional ideal (2*a - 1), Fractional ideal (3), Fractional ideal (3*a - 1), Fractional ideal (3*a - 2), Fractional ideal (-4*a + 1), Fractional ideal (-4*a + 3)]
319
"""
320
from misc import F
321
cdef long p=self.p, r=self.r
322
if r: # split and ramified cases
323
return F.ideal(p, F.gen()-r)
324
else: # inert case
325
return F.ideal(p)
326
327
from sage.rings.integer import Integer
328
329
def primes_above(long p, bint check=True):
330
"""
331
Return ordered list of all primes above p in the ring of integers
332
of Q(sqrt(5)). See the docstring for primes_of_bounded_norm.
333
334
INPUT:
335
- p -- prime number in integers ZZ (less than `2^{31}`)
336
- check -- bool (default: True); if True, check that p is prime
337
OUTPUT:
338
- list of 1 or 2 Prime objects
339
340
EXAMPLES::
341
342
sage: from psage.number_fields.sqrt5.prime import primes_above
343
sage: primes_above(2)
344
[2]
345
sage: primes_above(3)
346
[3]
347
sage: primes_above(5)
348
[5a]
349
sage: primes_above(11)
350
[11a, 11b]
351
sage: primes_above(13)
352
[13]
353
sage: primes_above(17)
354
[17]
355
sage: primes_above(4)
356
Traceback (most recent call last):
357
...
358
ValueError: p must be a prime
359
sage: primes_above(4, check=False)
360
[2]
361
"""
362
if check and not Integer(p).is_pseudoprime():
363
raise ValueError, "p must be a prime"
364
cdef long t = p%5
365
if t == 1 or t == 4 or t == 0:
366
return prime_range(p, p+1)
367
else: # inert
368
return [Prime(p, 0, True)]
369
370
def primes_of_bounded_norm(bound):
371
"""
372
Return ordered list of all prime ideals of the ring of integers of
373
Q(sqrt(5)) of norm less than bound.
374
375
The primes are instances of a special fast Primes class (they are
376
*not* usual Sage prime ideals -- use the sage_ideal() method to
377
get those). They are sorted first by norm, then in the remaining
378
split case by the integer in the interval [0,p) congruent to
379
(1+sqrt(5))/2.
380
381
INPUT:
382
- ``bound`` -- nonnegative integer, less than `2^{31}`
383
384
WARNING: The ordering is NOT the same as the ordering of primes by
385
Sage. Even if you order first by norm, then use Sage's ordering
386
for primes of the same norm, then the orderings do not agree.::
387
388
EXAMPLES::
389
390
sage: from psage.number_fields.sqrt5 import primes_of_bounded_norm
391
sage: primes_of_bounded_norm(0)
392
[]
393
sage: primes_of_bounded_norm(10)
394
[2, 5a, 3]
395
sage: primes_of_bounded_norm(50)
396
[2, 5a, 3, 11a, 11b, 19a, 19b, 29a, 29b, 31a, 31b, 41a, 41b, 7]
397
sage: len(primes_of_bounded_norm(10^6))
398
78510
399
400
We grab one of the primes::
401
402
sage: v = primes_of_bounded_norm(100)
403
sage: P = v[3]; type(P)
404
<type 'psage.number_fields.sqrt5.prime.Prime'>
405
406
It prints with a nice label::
407
408
sage: P
409
11a
410
411
You can get the corresponding fractional ideal as a normal Sage ideal::
412
413
sage: P.sage_ideal()
414
Fractional ideal (3*a - 1)
415
416
You can also get the underlying residue characteristic::
417
418
sage: P.p
419
11
420
421
And, the image of (1+sqrt(5))/2 modulo the prime (or 0 in the inert case)::
422
423
sage: P.r
424
4
425
sage: z = P.sage_ideal(); z.residue_field()(z.number_field().gen())
426
4
427
428
Prime enumeration is reasonable fast, even when the input is
429
relatively large (going up to `10^8` takes a few seconds, and up
430
to `10^9` takes a few minutes), and the following should take less
431
than a second::
432
433
sage: len(primes_of_bounded_norm(10^7)) # less than a second
434
664500
435
436
One limitation is that the bound must be less than `2^{31}`::
437
438
sage: primes_of_bounded_norm(2^31)
439
Traceback (most recent call last):
440
...
441
ValueError: bound must be less than 2^31
442
"""
443
return prime_range(bound)
444
445
def prime_range(long start, stop=None):
446
"""
447
Return ordered list of all prime ideals of the ring of integers of
448
Q(sqrt(5)) of norm at least start and less than stop. If only
449
start is given then return primes with norm less than start.
450
451
The primes are instances of a special fast Primes class (they are
452
*not* usual Sage prime ideals -- use the sage_ideal() method to
453
get those). They are sorted first by norm, then in the remaining
454
split case by the integer in the interval [0,p) congruent to
455
(1+sqrt(5))/2. For optimal speed you can use the Prime objects
456
directly from Cython, which provides direct C-level access to the
457
underlying data structure.
458
459
INPUT:
460
- ``start`` -- nonnegative integer, less than `2^{31}`
461
- ``stop`` -- None or nonnegative integer, less than `2^{31}`
462
463
EXAMPLES::
464
465
sage: from psage.number_fields.sqrt5.prime import prime_range
466
sage: prime_range(10, 60)
467
[11a, 11b, 19a, 19b, 29a, 29b, 31a, 31b, 41a, 41b, 7, 59a, 59b]
468
sage: prime_range(2, 11)
469
[2, 5a, 3]
470
sage: prime_range(2, 12)
471
[2, 5a, 3, 11a, 11b]
472
sage: prime_range(3, 12)
473
[2, 5a, 3, 11a, 11b]
474
sage: prime_range(9, 12)
475
[3, 11a, 11b]
476
sage: prime_range(5, 12)
477
[5a, 3, 11a, 11b]
478
"""
479
if start >= 2**31 or (stop and stop >= 2**31):
480
raise ValueError, "bound must be less than 2^31"
481
482
cdef long p, p2, sr, r0, r1, t, bound
483
cdef Prime P
484
cdef list v = []
485
486
if stop is None:
487
bound = start
488
start = 2
489
else:
490
bound = stop
491
492
from sage.all import prime_range as prime_range_ZZ
493
494
for p in prime_range_ZZ(bound, py_ints=True):
495
t = p % 5
496
if t == 1 or t == 4: # split
497
if p >= start:
498
# Compute a square root of 5 modulo p.
499
#sr = Fl_sqrt(5, p)
500
# Find the two values of (1+sqrt(5))/2.
501
#r0 = Fl_div(1+sr, 2, p)
502
# TODO fix
503
r1 = p+1-r0
504
# Sort
505
if r0 > r1: r0, r1 = r1, r0
506
# Append each prime to the list
507
P = PY_NEW(Prime); P.p = p; P.r = r0; P.first = True; v.append(P)
508
P = PY_NEW(Prime); P.p = p; P.r = r1; P.first = False; v.append(P)
509
elif p == 5: # ramified
510
if p >= start:
511
v.append(Prime(p, 3, True))
512
else:
513
p2 = p*p
514
if p2 < bound and p2 >= start:
515
v.append(Prime(p, 0, True))
516
517
v.sort()
518
return v
519
520
521
522
523
524
525