Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241852 views
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
"""
24
Cython code for very fast high precision computation of certain specific modular forms of interest.
25
"""
26
27
28
########################################
29
30
# The following functions are here mainly because computing f(q^d),
31
# for f(q) a power series, is by default quite slow in Sage, since
32
# FLINT's polynomial composition code is slow in this special case.
33
34
from sage.rings.rational cimport Rational
35
from sage.rings.integer cimport Integer
36
from sage.rings.polynomial.polynomial_rational_flint cimport Polynomial_rational_flint
37
from sage.libs.flint.fmpq_poly cimport (fmpq_poly_get_coeff_mpq, fmpq_poly_set_coeff_mpq,
38
fmpq_poly_length)
39
40
from sage.rings.polynomial.polynomial_integer_dense_flint cimport (Polynomial_integer_dense_flint,
41
fmpz_poly_set_coeff_mpz)
42
43
from sage.libs.gmp.mpq cimport mpq_numref
44
45
from sage.rings.all import ZZ
46
47
def _change_ring_ZZ(Polynomial_rational_flint f):
48
"""
49
Return the polynomial of numerators of coefficients of f.
50
51
INPUT:
52
- f -- a polynomial over the rational numbers with no denominators
53
OUTPUT:
54
- a polynomial over the integers
55
56
EXAMPLES::
57
58
sage: import psage.modform.rational.special_fast as s
59
sage: R.<q> = QQ[]
60
sage: f = 3 + q + 17*q^2 - 4*q^3 - 2*q^5
61
sage: g = s._change_ring_ZZ(f); g
62
-2*q^5 - 4*q^3 + 17*q^2 + q + 3
63
sage: g.parent()
64
Univariate Polynomial Ring in q over Integer Ring
65
66
Notice that the denominators are just uniformly ignored::
67
68
sage: f = 3/2 + -5/8*q + 17/3*q^2
69
sage: s._change_ring_ZZ(f)
70
17*q^2 - 5*q + 3
71
"""
72
cdef Polynomial_integer_dense_flint res = ZZ[f.parent().variable_name()](0)
73
cdef Rational x = Rational(0)
74
cdef unsigned long i
75
for i in range(fmpq_poly_length(f.__poly)):
76
fmpq_poly_get_coeff_mpq(x.value, f.__poly, i)
77
fmpz_poly_set_coeff_mpz(res.__poly, i, mpq_numref(x.value))
78
return res
79
80
def _evaluate_poly_at_power_of_gen(Polynomial_rational_flint f, unsigned long n, bint truncate):
81
"""
82
INPUT:
83
- f -- a polynomial over the rational numbers
84
- n -- a positive integer
85
- truncate -- bool; if True, truncate resulting polynomial so
86
it has coefficients up to deg(f) and possibly slightly more,
87
e.g., this is natural if we are interested in the power
88
series f+O(x^(d+1)).
89
90
OUTPUT:
91
- a polynomial over the rational numbers
92
93
EXAMPLES::
94
95
sage: import psage.modform.rational.special_fast as s
96
sage: R.<q> = QQ[]
97
sage: f = 2/3 + q + 17*q^2 - 4*q^3 - 2*q^5
98
sage: s._evaluate_poly_at_power_of_gen(f, 2, False)
99
-2*q^10 - 4*q^6 + 17*q^4 + q^2 + 2/3
100
sage: s._evaluate_poly_at_power_of_gen(f, 2, True)
101
-4*q^6 + 17*q^4 + q^2 + 2/3
102
"""
103
if n == 0:
104
raise ValueError, "n must be positive"
105
cdef Polynomial_rational_flint res = f._new()
106
cdef unsigned long k, m
107
cdef Rational z = Rational(0)
108
m = fmpq_poly_length(f.__poly)
109
if truncate:
110
m = m // n
111
for k in range(m+1):
112
fmpq_poly_get_coeff_mpq(z.value, f.__poly, k)
113
fmpq_poly_set_coeff_mpq(res.__poly, n*k, z.value)
114
return res
115
116
def _evaluate_series_at_power_of_gen(h, unsigned long n, bint truncate):
117
"""
118
INPUT:
119
- h -- a power series over the rational numbers
120
- n -- a positive integer
121
- if
122
123
OUTPUT:
124
- a power series over the rational numbers
125
126
EXAMPLES::
127
128
sage: import psage.modform.rational.special_fast as s
129
sage: R.<q> = QQ[[]]
130
sage: f = 2/3 + 3*q + 14*q^2 + O(q^3)
131
sage: s._evaluate_series_at_power_of_gen(f, 2, True)
132
2/3 + 3*q^2 + O(q^3)
133
sage: s._evaluate_series_at_power_of_gen(f, 2, False)
134
2/3 + 3*q^2 + 14*q^4 + O(q^5)
135
"""
136
# Return h(q^n) truncated to the precision of h massively quicker
137
# than writing "h(q^n)" in Sage.
138
f = _evaluate_poly_at_power_of_gen(h.polynomial(), n, truncate=truncate)
139
prec = h.prec() if truncate else (h.prec()-1) * n + 1
140
return h.parent()(f, prec)
141
142
143
144
def Integer_list_to_polynomial(list v, var='q'):
145
cdef Polynomial_integer_dense_flint res = ZZ[var](0)
146
cdef Py_ssize_t i
147
cdef Integer a
148
for i in range(len(v)):
149
a = v[i]
150
fmpz_poly_set_coeff_mpz(res.__poly, i, a.value)
151
return res
152
153
154