Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 views
1
r"""
2
Various functions needed for some calculations in the package.
3
4
AUTHORS:
5
6
- Martin Raum (2009 - 08 - 27) Initial version
7
"""
8
9
#===============================================================================
10
#
11
# Copyright (C) 2009 Martin Raum
12
#
13
# This program is free software; you can redistribute it and/or
14
# modify it under the terms of the GNU General Public License
15
# as published by the Free Software Foundation; either version 3
16
# of the License, or (at your option) any later version.
17
#
18
# This program is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
# General Public License for more details.
22
#
23
# You should have received a copy of the GNU General Public License
24
# along with this program; if not, see <http://www.gnu.org/licenses/>.
25
#
26
#===============================================================================
27
28
include "sage/ext/interrupt.pxi"
29
include 'sage/ext/stdsage.pxi'
30
include "sage/ext/cdefs.pxi"
31
include 'sage/ext/gmp.pxi'
32
33
from sage.rings.integer cimport Integer
34
35
cpdef divisor_dict(int precision) :
36
r"""
37
Return a dictionary of assigning to each `k <` ``precision`` a list of its divisors.
38
39
INPUT :
40
41
- precision -- a positive integer
42
"""
43
cdef int k
44
cdef int l
45
cdef int maxl
46
cdef int divisor
47
48
cdef mpz_t tmp
49
50
mpz_init(tmp)
51
52
mpz_set_si(tmp, precision)
53
mpz_sqrt(tmp, tmp)
54
bound = mpz_get_si(tmp) + 1
55
56
mpz_clear(tmp)
57
58
div_dict = PY_NEW(dict)
59
60
# these are the trivial divisors
61
div_dict[1] = [1]
62
for k from 2 <= k < precision :
63
div_dict[k] = [1,k]
64
65
for k from 2 <= k < bound // 2 :
66
divisor = 2*k
67
68
for l from 2 <= l < bound // k :
69
(<list>(div_dict[divisor])).append(k)
70
divisor += k
71
72
return div_dict
73
74
cpdef negative_fundamental_discriminants(int precision) :
75
r"""
76
Return a list of all negative fundamental discriminants `> -precision`
77
"""
78
cdef int *markers = <int *>malloc(precision * sizeof(int))
79
cdef int k
80
cdef int maxh
81
cdef int hs
82
83
cdef int tmp
84
cdef mpz_t mpz_tmp
85
86
mpz_init(mpz_tmp)
87
88
_sig_on
89
## consider congruences mod 4
90
for k from 1 <= k < precision :
91
tmp = k % 16
92
if tmp == 3 or tmp == 7 or tmp == 11 or tmp == 15 or tmp == 4 or tmp == 8 :
93
markers[k] = 1
94
else :
95
markers[k] = 0
96
97
mpz_set_si(mpz_tmp, precision)
98
mpz_sqrt(mpz_tmp, mpz_tmp)
99
maxh = mpz_get_si(mpz_tmp)
100
101
## consider square divisors
102
for h from 3 <= h < maxh :
103
hs = h*h
104
tmp = 0
105
106
for k from 1 <= k < precision // hs :
107
tmp += hs
108
markers[tmp] = 0
109
110
fund_discs = PY_NEW(list)
111
for k from 2 <= k < precision :
112
if markers[k] :
113
fund_discs.append(-k)
114
_sig_off
115
116
mpz_clear(mpz_tmp)
117
118
return fund_discs
119
120