Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
181 views
unlisted
ubuntu2004
1
r"""
2
Cache of computations of top xi evaluations and various evaluation of tautological classes.
3
"""
4
5
from ast import literal_eval
6
import os
7
import os.path
8
9
from sage.env import DOT_SAGE
10
import sage.misc.persist
11
12
from admcycles.diffstrata.adm_eval_cache import ADM_EVAL_CACHE
13
from admcycles.diffstrata.xi_cache import XI_TOP_CACHE
14
15
16
class Cache(dict):
17
r"""
18
Dictionary with synchronization in a ``.sobj`` file.
19
20
TESTS:
21
22
The synchronization files stores only diffs::
23
24
sage: from admcycles.diffstrata.cache import Cache
25
sage: filename = tmp_filename(ext='.sobj')
26
sage: C = Cache({2: 'two'}, filename=filename)
27
sage: C[3] = 'three'
28
sage: D = Cache(filename=filename)
29
sage: D
30
{3: 'three'}
31
32
An example without synchronization file::
33
34
sage: C = Cache({2: 'two'})
35
sage: C[3] = 'three'
36
sage: C
37
{2: 'two', 3: 'three'}
38
"""
39
40
def __init__(self, values=None, filename=None):
41
self._filename = filename
42
if values is None:
43
self._default = {}
44
dict.__init__(self)
45
else:
46
self._default = values.copy()
47
dict.__init__(self, values)
48
self.update_from_sobj_file(self._filename)
49
50
def reset_default(self):
51
r"""
52
Reset the content of the dictionary to the set of default values.
53
54
TESTS::
55
56
sage: from admcycles.diffstrata.cache import Cache
57
sage: C = Cache({1: 'ein', 2: 'zwei'})
58
sage: C[3] = 'drei'
59
sage: sorted(C.keys())
60
[1, 2, 3]
61
sage: C.reset_default()
62
sage: sorted(C.keys())
63
[1, 2]
64
"""
65
self.clear()
66
self.update(self._default)
67
68
def update_from_sobj_file(self, filename=None):
69
r"""
70
Update the values of this dictionary from a ``.sobj`` file.
71
72
Missing or empty files are ignored. The cache file is synchronized.
73
74
EXAMPLES::
75
76
sage: from admcycles.diffstrata.cache import Cache
77
sage: filename1 = tmp_filename(ext='.sobj')
78
sage: filename2 = tmp_filename(ext='.sobj')
79
sage: C1 = Cache({2: 'two'}, filename=filename1)
80
sage: C1[3] = 'three'
81
sage: C2 = Cache(filename=filename2)
82
sage: C2
83
{}
84
sage: C2.update_from_sobj_file(filename1)
85
sage: Cache(filename=filename2)
86
{3: 'three'}
87
"""
88
if filename is None:
89
filename = self._filename
90
if filename is not None and os.path.isfile(
91
filename) and os.stat(filename).st_size:
92
self.update(sage.misc.persist.load(filename))
93
if filename != self._filename:
94
self.save_to_sobj_file()
95
96
def diff(self):
97
cache = self.copy()
98
for key in self._default:
99
del cache[key]
100
return cache
101
102
def save_to_sobj_file(self, filename=None, only_diff=True):
103
r"""
104
Save the values of this dictionary to a ``.sobj`` file.
105
"""
106
if filename is None:
107
filename = self._filename
108
if filename is not None:
109
cache = self.diff() if only_diff else self.copy()
110
if cache:
111
sage.misc.persist.save(cache, filename)
112
113
def __setitem__(self, key, value):
114
dict.__setitem__(self, key, value)
115
self.save_to_sobj_file()
116
117
118
class FakeCache(Cache):
119
r"""
120
A cache where ``__setitem__`` does not do anything.
121
122
This class is intended for benchmarking without caching.
123
124
TESTS::
125
126
sage: from admcycles.diffstrata.cache import FakeCache
127
sage: C = FakeCache()
128
sage: C[3] = 'trois'
129
sage: C
130
{}
131
"""
132
133
def __setitem__(self, key, value):
134
pass
135
136
137
ADM_EVALS_FILENAME = os.path.join(DOT_SAGE, 'adm_evals.sobj')
138
TOP_XIS_FILENAME = os.path.join(DOT_SAGE, 'top_xis.sobj')
139
140
ADM_EVALS = Cache(ADM_EVAL_CACHE, ADM_EVALS_FILENAME)
141
TOP_XIS = Cache(XI_TOP_CACHE, TOP_XIS_FILENAME)
142
143
144
def list_top_xis(xi_dict=TOP_XIS):
145
"""
146
A generator for decyphering LevelStratum.dict_key
147
148
By default, the xi cache is used, alternatively a different
149
cache dictionary may be specified.
150
151
Args:
152
xi_dict (dict, optional): cache dictionary. Defaults to ``TOP_XIS``.
153
154
Yields:
155
tuple: signature list, residue conditions, top xi evaluation
156
"""
157
for key in sorted(xi_dict):
158
sig_list, rcs = key
159
yield (sig_list, rcs, xi_dict[key])
160
161
162
def print_top_xis(xi_dict=TOP_XIS):
163
"""
164
The top xi powers in the cache are printed in human-readable form.
165
166
Alternatively, any valid xi cache dictionary may be specified.
167
168
The dimensions of the table might have to be adapted to console size and
169
complexity of the involved strata.
170
171
Args:
172
xi_dict (dict, optional): xi cache dictionary. Defaults to ``TOP_XIS``.
173
174
EXAMPLES::
175
176
sage: from admcycles.diffstrata import print_top_xis
177
sage: from admcycles.diffstrata.cache import TOP_XIS
178
sage: TOP_XIS.reset_default()
179
sage: print_top_xis()
180
Stratum | Residue Conditions | xi^dim
181
--------------------------------------------------------------------------------------------------
182
(-8, -2, 8) | [(0, 0), (0, 1)] | 1
183
(-8, 0, 6) | [(0, 0)] | 1
184
(-8, 1, 1, 2, 2) | [(0, 0)] | 49
185
...
186
(3, 3) | () | 0
187
(4,) | () | 305/580608
188
(6,) | () | -87983/199065600
189
(8,) | () | 339849/504627200
190
"""
191
LEFT = 40
192
MIDDLE = 45
193
RIGHT = 13
194
print('{:<{width}}'.format('Stratum', width=LEFT) + '|' +
195
'{:<{width}}'.format(' Residue Conditions', width=MIDDLE) + '|' +
196
'{:<{width}}'.format(' xi^dim', width=RIGHT))
197
print('-' * (LEFT + MIDDLE + RIGHT))
198
for sig_list, res_conds, xi in list_top_xis(xi_dict):
199
if len(sig_list) == 1:
200
sig = sig_list[0]
201
else:
202
sig = list(sig_list)
203
if not res_conds:
204
rcs = tuple()
205
else:
206
if len(res_conds) == 1:
207
rcs = list(res_conds[0])
208
else:
209
rcs = [list(c) for c in res_conds]
210
print('{:<{width}}'.format(str(sig), width=LEFT) + '| ' +
211
'{:<{width}}'.format(str(rcs), width=MIDDLE - 1) + '| ' +
212
'{:<{width}}'.format(str(xi), width=RIGHT - 1))
213
214
215
def print_adm_evals(adm_dict=ADM_EVALS):
216
"""
217
The cached evaluations are printed in human-readable form.
218
219
Alternatively, any valid adm cache dictionary may be specified (see load_adm_evals
220
for details on the format).
221
222
The dimensions of the table might have to be adapted to console size and
223
complexity of the involved strata.
224
225
Args:
226
adm_dict (dict, optional): evaluations cache dictionary. Defaults to None.
227
228
EXAMPLES::
229
230
sage: from admcycles.diffstrata import print_adm_evals
231
sage: from admcycles.diffstrata.cache import ADM_EVALS
232
sage: ADM_EVALS.reset_default()
233
sage: print_adm_evals()
234
Stratum | Psis | eval
235
--------------------------------------------------------------------------------------------------
236
...
237
(2,) | {1: 3} | 1/1920
238
(2, 2) | {1: 1, 2: 5} | 71/322560
239
(2, 2) | {1: 2, 2: 4} | 13/53760
240
(2, 2) | {1: 3, 2: 3} | 13/53760
241
(2, 2) | {1: 6} | 43/322560
242
(4,) | {1: 5} | 13/580608
243
(6,) | {1: 7} | 281/199065600
244
"""
245
LEFT = 40
246
MIDDLE = 45
247
RIGHT = 13
248
print('{:<{width}}'.format('Stratum', width=LEFT) + '|' +
249
'{:<{width}}'.format(' Psis', width=MIDDLE) + '|' +
250
'{:<{width}}'.format(' eval', width=RIGHT))
251
print('-' * (LEFT + MIDDLE + RIGHT))
252
for key in sorted(adm_dict): # sort by stratum
253
sig, psis = key
254
value = adm_dict[key]
255
dpsis = dict(psis)
256
print('{:<{width}}'.format(str(sig), width=LEFT) + '| ' +
257
'{:<{width}}'.format(str(dpsis), width=MIDDLE - 1) + '| ' +
258
'{:<{width}}'.format(str(value), width=RIGHT - 1))
259
260
261
def jsonify_dict(d):
262
json_dict = {}
263
for k, v in d.items():
264
json_dict[str(k)] = v
265
return json_dict
266
267
268
def unjsonify_dict(json_dict):
269
restored_dict = {}
270
for k, v in json_dict.items():
271
restored_dict[literal_eval(k)] = v
272
return restored_dict
273
274
275
def import_adm_evals(filename):
276
"""
277
Import a dictionary of the form adm_key : value into the cache.
278
279
Args:
280
filename (String): sobj filename
281
"""
282
ADM_EVALS.update_from_sobj_file(filename)
283
284
285
def import_top_xis(filename):
286
"""
287
Import a dictionary of the form LevelStratum.dict_key : value into the cache.
288
289
Args:
290
filename (String): sobj filename
291
"""
292
TOP_XIS.update_from_sobj_file(filename)
293
294
295
def load_adm_evals():
296
"""
297
The cache dictionary for the admcycles evaluations (via GeneralisedStratum.adm_evaluate)
298
299
The cache dictionary is of the form:
300
301
adm_key -> GeneralisedStratum.adm_evaluate(adm_key) (a rational number)
302
303
Returns:
304
dict: cache dictionary
305
"""
306
return ADM_EVALS
307
308
309
def load_xis():
310
"""
311
The cache dictionary for the top xi powers (evaluated)
312
313
The cache dictionary is of the form:
314
315
L.dict_key -> (L.xi)^L.dim().evaluate() (a rational number)
316
317
for a LevelStratum L.
318
319
Returns:
320
dict: cache dictionary
321
"""
322
return TOP_XIS
323
324