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