Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 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 2 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
include 'interrupt.pxi'
23
24
from sage.finance.time_series cimport TimeSeries
25
from sage.stats.intlist cimport IntList
26
27
cdef extern:
28
double log(double)
29
double sqrt(double)
30
double cos(double)
31
double sin(double)
32
33
cdef class J:
34
cdef long N_max
35
cdef TimeSeries a, s
36
cdef IntList pv
37
38
def __init__(self, int N_max=10**5):
39
from sage.all import prime_powers, factor
40
self.N_max = N_max
41
PP = prime_powers(N_max+1)[1:]
42
43
cdef double logp
44
cdef int i, n = len(PP)
45
self.a = TimeSeries(n)
46
self.s = TimeSeries(n)
47
self.pv = IntList(n)
48
i = 0
49
for pv in PP:
50
F = factor(pv)
51
p, v = F[0]
52
self.pv._values[i] = pv
53
logp = log(p)
54
self.a._values[i] = logp/sqrt(pv)
55
self.s._values[i] = v*logp
56
i += 1
57
58
def __repr__(self):
59
return "The function J(t,N) of the Mazur-Stein game with N_Max=%s"%self.N_max
60
61
cpdef double F(self, double t, int N):
62
cdef double ans = 0
63
cdef int i = 0
64
if N > self.N_max:
65
raise ValueError, "J not defined for N > %s"%self.N_max
66
while 1:
67
if self.pv._values[i] >= N:
68
return ans
69
ans += self.a._values[i] * cos(self.s._values[i]*t)
70
i += 1
71
72
cpdef double e(self, double t, int N):
73
return sqrt(N)/(.25 + t*t) * \
74
( cos(t*log(N)) + 2*t*sin(t*log(N)) )
75
76
cpdef double H(self, double t, int N):
77
cdef double ans = 0, F = 0
78
cdef int i = 0, n
79
if N > self.N_max:
80
raise ValueError, "J not defined for N > %s"%self.N_max
81
n = 1
82
_sig_on
83
while 1:
84
if self.pv._values[i] > N:
85
# time to return. But first we have to add a few more
86
# values to ans up to N (where F is constant).
87
while n <= N:
88
ans += F + self.e(t,n)
89
#print (n, F, self.e(t,n))
90
n += 1
91
# Finally return after dividing by N.
92
_sig_off
93
return ans / N
94
# At this point, F is equal to self.F(t, self.pv._values[i]),
95
# and now we add to our running total a range of values of
96
97
# F(t, n) + e(t,n)
98
while n <= self.pv._values[i]:
99
ans += F + self.e(t,n)
100
#print (n, F, self.e(t,n))
101
n += 1
102
103
F += self.a._values[i] * cos(self.s._values[i]*t)
104
105
# move to next prime power
106
i += 1
107
108
cpdef double J(self, double t, int N):
109
return self.H(t,N) / log(N)
110
111
def __call__(self, double t, int N):
112
return self.J(t,N)
113
114
cpdef double H2(self, double t, int N):
115
cdef int n
116
return sum([self.F(t,n) + self.e(t,n) for n in range(1,N+1)]) / N
117
118
cpdef double J2(self, double t, int N):
119
return self.H2(t, N) / log(N)
120
121
######################################################
122
# Cesaro of Cesaro...
123
######################################################
124
def Jc(self, double t, int N):
125
cdef double ans = 0, F = 0, ans2 = 0
126
cdef int i = 0, n
127
if N > self.N_max:
128
raise ValueError, "J not defined for N > %s"%self.N_max
129
n = 1
130
_sig_on
131
while 1:
132
if self.pv._values[i] > N:
133
# time to return. But first we have to add a few more
134
# values to ans up to N (where F is constant).
135
while n <= N:
136
ans += F + self.e(t,n)
137
if n >= 2:
138
ans2 += ans / (n*log(n))
139
#print (n, F, self.e(t,n))
140
n += 1
141
# Finally return after dividing by N.
142
_sig_off
143
return ans2 / N
144
# At this point, F is equal to self.F(t, self.pv._values[i]),
145
# and now we add to our running total a range of values of
146
147
# F(t, n) + e(t,n)
148
while n <= self.pv._values[i]:
149
ans += F + self.e(t,n)
150
if n >= 2:
151
ans2 += ans / (n*log(n))
152
#print (n, F, self.e(t,n))
153
n += 1
154
155
F += self.a._values[i] * cos(self.s._values[i]*t)
156
157
# move to next prime power
158
i += 1
159
160
def cesaro_sum(TimeSeries x, TimeSeries y):
161
"""
162
Given the graph of a function defined by (x[i], y[i]), compute its
163
Cesaro smoothing. This function returns a new series giving the y
164
values of the Cesaro smoothing evaluated at the same values of x.
165
"""
166
assert len(x) == len(y)
167
cdef Py_ssize_t n
168
cdef TimeSeries yc = TimeSeries(len(y))
169
yc._values[0] = 0
170
for n in range(1, len(x)):
171
yc._values[n] = (x._values[n] - x._values[n-1])*y._values[n] + yc._values[n-1]
172
173
for n in range(1,len(x)):
174
yc._values[n] /= (x._values[n] - x._values[0])
175
return yc
176
177
def average_value_function(v):
178
"""Given a list v = [...,(x,y),...] of points with the x's
179
increasing that defines a piecewise linear function y=f(x),
180
compute and return the average value function (1/z)*int_{v[0][0]}^z f(x)dx,
181
expressed again as a list with the same x's.
182
"""
183
raise NotImplementedError
184
185
def plot_with_averages(v):
186
"""Given a list v = [...,(x,y),...] of points with the x's increasing, plot the function
187
through these points, along with the graph in red of the average value of this function
188
"""
189
from sage.all import line
190
a = average_value_function(v)
191
return line(v) + line(a, color='red')
192
193
194
###############################################################################
195
# J with a character
196
###############################################################################
197
198
cdef class J_chi(J):
199
cdef bint _e
200
def __init__(self, chi, int N_max=10**5, e=False):
201
self._e = e
202
# This is exactly the init from J, but the
203
# definition of self.a._values[i] is changed below.
204
from sage.all import prime_powers, factor
205
self.N_max = N_max
206
PP = prime_powers(N_max+1)[1:]
207
208
cdef double logp
209
cdef int i, n = len(PP)
210
self.a = TimeSeries(n)
211
self.s = TimeSeries(n)
212
self.pv = IntList(n)
213
i = 0
214
for pv in PP:
215
F = factor(pv)
216
p, v = F[0]
217
self.pv._values[i] = pv
218
logp = log(p)
219
self.a._values[i] = logp/sqrt(pv) * chi(pv)
220
self.s._values[i] = v*logp
221
i += 1
222
223
cpdef double e(self, double t, int N):
224
if self._e:
225
return sqrt(N)/(.25 + t*t) * \
226
( cos(t*log(N)) + 2*t*sin(t*log(N)) )
227
else:
228
return 0
229
230
231