Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241852 views
1
r"""
2
An equivariant monoid power series with lazy evaluation.
3
4
AUTHOR :
5
-- Martin Raum (2009 - 08 - 05) Initial version
6
"""
7
8
#===============================================================================
9
#
10
# Copyright (C) 2009 Martin Raum
11
#
12
# This program is free software; you can redistribute it and/or
13
# modify it under the terms of the GNU General Public License
14
# as published by the Free Software Foundation; either version 3
15
# of the License, or (at your option) any later version.
16
#
17
# This program is distributed in the hope that it will be useful,
18
# but WITHOUT ANY WARRANTY; without even the implied warranty of
19
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
# General Public License for more details.
21
#
22
# You should have received a copy of the GNU General Public License
23
# along with this program; if not, see <http://www.gnu.org/licenses/>.
24
#
25
#===============================================================================
26
27
from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ambient import EquivariantMonoidPowerSeriesAmbient_abstract
28
from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import EquivariantMonoidPowerSeries_abstract
29
from sage.algebras.algebra_element import AlgebraElement
30
from sage.misc.misc import union
31
from sage.modules.module import Module
32
from sage.modules.module_element import ModuleElement
33
from sage.rings.ring import Ring
34
35
#===============================================================================
36
# EquivariantMonoidPowerSeries_lazy
37
#===============================================================================
38
39
def EquivariantMonoidPowerSeries_lazy(parent, precision, coefficient_function, components = None, bounding_precision = None) :
40
r"""
41
Construct a equivariant monoid power series, which calculates its coefficients
42
on demand.
43
44
INPUT:
45
- ``parent`` -- An instance of :class:~`fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ambient.MonoidPowerSeriesAmbient_abstract`.
46
- ``precision`` -- A filter for the parent's action.
47
- ``coefficient_function`` -- A function returning for each pair of characters and
48
monoid element a Fourier coefficients.
49
- ``components`` -- ``None`` or a list of characters (default: ``None``). A list of components
50
that do not vanish. If ``None`` no component is assumed to be zero.
51
- ``bounding_precision`` -- ``None`` or a filter for the parent's action. If not ``None``
52
coefficients will be assumed to vanish outside the filter.
53
54
OUTPUT:
55
An instance of :class:~`EquivariantMonoidPowerSeries_abstract_lazy`.
56
57
EXAMPLES::
58
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
59
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
60
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_module import *
61
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
62
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
63
sage: h = EquivariantMonoidPowerSeries_lazy(emps, emps.action().filter(3), lambda (ch, k) : 1)
64
sage: m = FreeModule(QQ, 3)
65
sage: emps = EquivariantMonoidPowerSeriesModule( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", m) )
66
sage: h = EquivariantMonoidPowerSeries_lazy(emps, emps.action().filter(3), lambda (ch, k) : m([1,2,3]))
67
sage: h = EquivariantMonoidPowerSeries_lazy(emps, emps.action().filter_all(), lambda (ch, k) : m([1,2,3]), bounding_precision = emps.action().filter(2))
68
sage: h = EquivariantMonoidPowerSeries_lazy(emps, emps.action().filter_all(), lambda (ch, k) : m([1,2,3]))
69
Traceback (most recent call last):
70
...
71
ValueError: Lazy equivariant monoid power series cannot have infinite precision.
72
"""
73
if (bounding_precision is None or bounding_precision.is_infinite()) and \
74
precision.is_infinite() and not (isinstance(components, list) and len(components) == 0) :
75
raise ValueError( "Lazy equivariant monoid power series cannot have infinite precision." )
76
if isinstance(parent, Module) :
77
return EquivariantMonoidPowerSeries_moduleelement_lazy(parent, precision, coefficient_function, components, bounding_precision)
78
if isinstance(parent, Ring) :
79
return EquivariantMonoidPowerSeries_algebraelement_lazy(parent, precision, coefficient_function, components, bounding_precision)
80
81
#===============================================================================
82
# EquivariantMonoidPowerSeries_abstract_lazy
83
#===============================================================================
84
85
class EquivariantMonoidPowerSeries_abstract_lazy (EquivariantMonoidPowerSeries_abstract) :
86
r"""
87
This class implements an equivariant monoid power series which calculates the
88
coefficients on demand.
89
"""
90
91
def __init__(self, parent, precision, coefficient_function, components, bounding_precision = None ) :
92
r"""
93
INPUT:
94
- ``parent`` -- An instance of :class:~`fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ambient.MonoidPowerSeriesAmbient_abstract`.
95
- ``precision`` -- A filter for the parent's action.
96
- ``coefficient_function`` -- A function returning for each pair of characters and
97
monoid element a Fourier coefficients.
98
- ``components`` -- ``None`` or a list of characters. A list of components that do not
99
vanish. If ``None`` no component is assumed to be zero.
100
- ``bounding_precision`` -- ``None`` or a filter for the parent's action. If not ``None``
101
coefficients will be assumed to vanish outside the filter.
102
103
TESTS::
104
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
105
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
106
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
107
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
108
sage: h = EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter(3), lambda (ch, k) : 1, None)
109
sage: h = EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter(3), lambda (ch, k) : 1, [])
110
sage: h = EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter_all(), lambda (ch, k) : 1, [], emps.action().filter(4))
111
"""
112
EquivariantMonoidPowerSeries_abstract.__init__(self, parent, precision)
113
114
self.__bounding_precision = bounding_precision
115
self.__coefficient_function = coefficient_function
116
self.__coefficients = dict()
117
self.__coefficients_complete = False
118
self.__components = components
119
120
def non_zero_components(self) :
121
r"""
122
Return all those characters which are not guaranteed to have only
123
vanishing coefficients associated with.
124
125
OUTPUT:
126
A list of elements of the character monoid.
127
128
NOTE:
129
This will only return the list passed during the construction
130
of self or a list of all characters.
131
132
EXAMPLES::
133
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
134
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *
135
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
136
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
137
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
138
sage: e = EquivariantMonoidPowerSeries(emps, {emps.characters().one_element() : { 1 : 1}}, emps.action().filter_all())
139
sage: EquivariantMonoidPowerSeries_LazyMultiplication(e, e).non_zero_components()
140
[1]
141
sage: EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter(3), lambda (ch, k) : 1, []).non_zero_components()
142
[]
143
"""
144
if self.__components is None :
145
self.__components = [c for c in self.parent().characters()]
146
147
return self.__components
148
149
def _bounding_precision(self) :
150
r"""
151
If a filter for the vanishing of coefficients is given return this. Otherwise,
152
return the precision, which is then guaranteed to be finite.
153
154
OUTPUT:
155
A filter for the parent's action.
156
157
TESTS::
158
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
159
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *
160
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
161
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
162
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
163
sage: e = EquivariantMonoidPowerSeries(emps, {}, emps.action().filter_all())
164
sage: EquivariantMonoidPowerSeries_LazyMultiplication(e, e)._bounding_precision()
165
Filtered NN with action up to 0
166
sage: EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter(3), lambda (ch, k) : 1, [emps.characters().one_element()])._bounding_precision()
167
Filtered NN with action up to 3
168
sage: h = EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter_all(), lambda (ch, k) : 1, [])._bounding_precision() ## This would call the parent
169
Traceback (most recent call last):
170
...
171
AttributeError: EquivariantMonoidPowerSeries_abstract_lazy instance has no attribute 'parent'
172
sage: h = EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter_all(), lambda (ch, k) : 1, [], emps.action().filter(4))._bounding_precision() ## This would call the parent
173
Traceback (most recent call last):
174
...
175
AttributeError: EquivariantMonoidPowerSeries_abstract_lazy instance has no attribute 'parent'
176
sage: EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter_all(), lambda (ch, k) : 1, [emps.characters().one_element()], emps.action().filter(4))._bounding_precision()
177
Filtered NN with action up to 4
178
sage: EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter_all(), lambda (ch, k) : 1, [emps.characters().one_element()])._bounding_precision()
179
Traceback (most recent call last):
180
...
181
ValueError: No bounding precision for ...
182
"""
183
if len(self.non_zero_components()) == 0 :
184
return self.parent().action().zero_filter()
185
elif not self.__bounding_precision is None :
186
return min(self.__bounding_precision, self.precision())
187
elif self.precision().is_infinite() :
188
raise ValueError( "No bounding precision for %s." % (self,) )
189
190
return self.precision()
191
192
def coefficients(self, force_characters = False) :
193
r"""
194
Evaluate all coefficients within the precision bounds and return a
195
dictionary which saves all coefficients of this element.
196
197
INPUT:
198
- ``force_characters`` -- A boolean (default: ``False``); If ``True`` the
199
the dictionary returned will have characters as keys
200
in any cases.
201
202
OUTPUT:
203
Either of the following two:
204
- A dictionary with keys the elements of the parent's monoid and values in the
205
parent's coefficient domain.
206
- A dictionary with keys the parent's characters and values the a dictionary as follows. This
207
dictionary has keys the elements of the parent's monoid and values in the parent's
208
coefficient domain.
209
210
EXAMPLES::
211
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
212
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
213
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
214
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
215
sage: e = EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter(3), lambda (ch, k) : 1, [emps.characters().one_element()])
216
sage: e.coefficients()
217
{0: 1, 1: 1, 2: 1}
218
sage: e.coefficients(True)
219
{1: {0: 1, 1: 1, 2: 1}}
220
"""
221
if not self.__coefficients_complete :
222
self.__coefficients_complete = True
223
224
coefficient_function = self.__coefficient_function
225
226
for ch in self.non_zero_components() :
227
if not ch in self.__coefficients :
228
coeffs = dict()
229
self.__coefficients[ch] = coeffs
230
for k in self._bounding_precision() :
231
coeffs[k] = coefficient_function((ch, k))
232
else :
233
coeffs = self.__coefficients[ch]
234
for k in self._bounding_precision() :
235
if not k in coeffs :
236
coeffs[k] = coefficient_function((ch, k))
237
238
if len(self.__coefficients) == 0 and not force_characters :
239
return dict()
240
elif len(self.__coefficients) == 1 and not force_characters :
241
return self.__coefficients.values()[0]
242
else :
243
return self.__coefficients
244
245
def _truncate_in_place(self, precision) :
246
r"""
247
Truncate ``self`` modifying also the coefficient cache.
248
249
INPUT:
250
- ``precision`` -- A filter for the parent's action or a an object that can be converted
251
to a filter.
252
253
OUTPUT:
254
``None``
255
256
EXAMPLE:
257
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
258
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *
259
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
260
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
261
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
262
sage: h = EquivariantMonoidPowerSeries_abstract_lazy(emps, emps.action().filter(3), lambda (ch, k) : 1, None)
263
sage: e = EquivariantMonoidPowerSeries(emps, {emps.characters().one_element() : { 1 : 1}}, emps.action().filter_all())
264
sage: e = EquivariantMonoidPowerSeries_LazyMultiplication(e, e)
265
sage: e._truncate_in_place(emps.monoid().filter(2))
266
sage: e.coefficients()
267
{0: 0, 1: 0}
268
"""
269
precision = self.parent().action().filter(precision)
270
nprec = min(self.precision(), precision)
271
272
if nprec != self.precision() :
273
for c in self.__coefficients :
274
d = self.__coefficients[c]
275
for k in d.keys() :
276
if not k in nprec :
277
del d[k]
278
279
self._set_precision(nprec)
280
281
def __getitem__(self, k) :
282
r"""
283
Evaluate and return the `k`-th coefficient if it below the series' precision. If no character is contained
284
in the key ``self`` must have only one nonvanishing component.
285
286
INPUT:
287
- `k` -- A pair of an element of the parent's character monoid and
288
and element of the parent's monoid or an element of the parent's monoid.
289
290
OUTPUT:
291
An element of the parent's coefficient domain.
292
293
EXAMPLES::
294
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
295
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *
296
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
297
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
298
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
299
sage: e = EquivariantMonoidPowerSeries(emps, {emps.characters().one_element() : { 1 : 1, 2 : 4}}, emps.action().filter(3))
300
sage: e = EquivariantMonoidPowerSeries_LazyMultiplication(e, e)
301
sage: e[(emps.characters().one_element(),2)]
302
1
303
sage: e[1], e[2]
304
(0, 1)
305
"""
306
try :
307
(ch, s) = k
308
except TypeError :
309
ch = None
310
311
try :
312
if not ch.parent() == self.parent().characters() :
313
ch = None
314
except AttributeError :
315
ch = None
316
317
if ch is None :
318
ns = self.non_zero_components()
319
if len(ns) == 0 :
320
return 0
321
elif len(ns) == 1 :
322
ch = ns[0]
323
else :
324
raise ValueError, "you must specify a character"
325
326
s = k
327
328
if not s in self.precision() :
329
raise ValueError, "%s out of bound" % s
330
331
try :
332
return self.__coefficients[ch][s]
333
except KeyError :
334
(rs, g) = self.parent()._reduction_function()(s)
335
try :
336
return self.parent()._character_eval_function()(g, ch) \
337
* self.parent()._apply_function()(g, self.__coefficients[ch][rs])
338
except KeyError :
339
e = self.__coefficient_function((ch, rs))
340
341
try :
342
self.__coefficients[ch][rs] = e
343
except KeyError :
344
self.__coefficients[ch] = dict()
345
self.__coefficients[ch][rs] = e
346
347
return e
348
349
#===============================================================================
350
# EquivariantMonoidPowerSeries_modulelement_lazy
351
#===============================================================================
352
353
class EquivariantMonoidPowerSeries_moduleelement_lazy (EquivariantMonoidPowerSeries_abstract_lazy, ModuleElement) :
354
r"""
355
A lazy element of a module of equivariant monoid power series.
356
"""
357
358
def __init__(self, parent, precision, coefficient_function, components, bounding_precision ) :
359
r"""
360
INPUT:
361
- ``parent`` -- An instance of :class:~`fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ambient.MonoidPowerSeriesAmbient_abstract`.
362
- ``precision`` -- A filter for the parent's action.
363
- ``coefficient_function`` -- A function returning for each pair of characters and
364
monoid element a Fourier coefficients.
365
- ``components`` -- ``None`` or a list of characters. A list of components that do not
366
vanish. If ``None`` no component is assumed to be zero.
367
368
TESTS::
369
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
370
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_module import *
371
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
372
sage: m = FreeModule(QQ, 3)
373
sage: emps = EquivariantMonoidPowerSeriesModule( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", m) )
374
sage: h = EquivariantMonoidPowerSeries_moduleelement_lazy(emps, emps.action().filter(3), lambda (ch, k) : m([1,2,3]), None, None)
375
"""
376
ModuleElement.__init__(self, parent)
377
EquivariantMonoidPowerSeries_abstract_lazy.__init__(self, parent, precision,
378
coefficient_function, components, bounding_precision)
379
380
#===============================================================================
381
# EquivariantMonoidPowerSeries_algebraelement_lazy
382
#===============================================================================
383
384
class EquivariantMonoidPowerSeries_algebraelement_lazy (EquivariantMonoidPowerSeries_abstract_lazy, AlgebraElement) :
385
r"""
386
A lazy element of an algebra of equivariant monoid power series.
387
"""
388
389
def __init__(self, parent, precision, coefficient_function, components, bounding_precision ) :
390
r"""
391
INPUT:
392
- ``parent`` -- An instance of :class:~`fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ambient.MonoidPowerSeriesAmbient_abstract`.
393
- ``precision`` -- A filter for the parent's action.
394
- ``coefficient_function`` -- A function returning for each pair of characters and
395
monoid element a Fourier coefficients.
396
- ``components`` -- ``None`` or a list of characters. A list of components that do not
397
vanish. If ``None`` no component is assumed to be zero.
398
399
TESTS::
400
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
401
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
402
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
403
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
404
sage: h = EquivariantMonoidPowerSeries_algebraelement_lazy(emps, emps.action().filter(3), lambda (ch, k) : 1, None, None)
405
"""
406
AlgebraElement.__init__(self, parent)
407
EquivariantMonoidPowerSeries_abstract_lazy.__init__(self, parent, precision,
408
coefficient_function, components, bounding_precision)
409
410
#===============================================================================
411
# EquivariantMonoidPowerseries_MultiplicationDelayedFactory
412
#===============================================================================
413
414
class EquivariantMonoidPowerseries_MultiplicationDelayedFactory :
415
r"""
416
A helper class for lazy multplication of equivariant monoid power series.
417
"""
418
419
def __init__( self, left, right ) :
420
r"""
421
INPUT:
422
- ``left`` -- An instance of :class:~`fourier_expansion_framework.monoidpowerseries.EquivariantMonoidPowerSeries_abstract`.
423
- ``right`` -- An instance of :class:~`fourier_expansion_framework.monoidpowerseries.EquivariantMonoidPowerSeries_abstract`.
424
425
NOTE:
426
``left`` and ``right`` must have the same parents.
427
428
TESTS::
429
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
430
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *
431
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
432
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
433
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
434
sage: e = EquivariantMonoidPowerSeries(emps, {emps.characters().one_element() : { 1 : 1}}, emps.action().filter_all())
435
sage: EquivariantMonoidPowerSeries_LazyMultiplication(e, e).coefficients() # indirect doctest
436
{0: 0, 1: 0, 2: 1}
437
"""
438
assert left.parent() == right.parent()
439
440
self.__left = left
441
self.__right = right
442
443
self.__mul_fc = left.parent()._multiply_function()
444
self.__coefficient_ring = left.parent().coefficient_domain()
445
446
self.__left_coefficients = None
447
self.__right_coefficients = None
448
449
def getcoeff(self, (ch, k)) :
450
r"""
451
Return the `k`-th coefficient of the component ``ch`` of the product.
452
453
INPUT:
454
- ``(ch, k)`` -- A pair of character and monoid element.
455
456
TESTS::
457
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
458
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *
459
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
460
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
461
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
462
sage: e = EquivariantMonoidPowerSeries(emps, {emps.characters().one_element() : { 1 : 1}}, emps.action().filter_all())
463
sage: EquivariantMonoidPowerSeries_LazyMultiplication(e, e).coefficients() # indirect doctest
464
{0: 0, 1: 0, 2: 1}
465
"""
466
res = self.__coefficient_ring(0)
467
468
if self.__left_coefficients is None :
469
self.__left_coefficients = self.__left.coefficients(True)
470
if self.__right_coefficients is None :
471
self.__right_coefficients = self.__right.coefficients(True)
472
473
for c1 in self.__left_coefficients :
474
lcoeffs = self.__left_coefficients[c1]
475
if len(lcoeffs) == 0 : continue
476
477
for c2 in self.__right_coefficients :
478
rcoeffs = self.__right_coefficients[c2]
479
if len(rcoeffs) == 0 : continue
480
481
if c1 * c2 != ch :
482
continue
483
484
res += self.__mul_fc( k, lcoeffs, rcoeffs, c1, c2, self.__coefficient_ring(0) )
485
486
return res
487
488
#===============================================================================
489
# EquivariantMonoidPowerSeries_LazyMultiplication
490
#===============================================================================
491
492
def EquivariantMonoidPowerSeries_LazyMultiplication(left, right) :
493
r"""
494
The product of two equivariant monoid power series which is only evaluated
495
if a coefficient is demanded.
496
497
INPUT:
498
- ``left`` -- An instance of :class:~`fourier_expansion_framework.monoidpowerseries.EquivariantMonoidPowerSeries_abstract`.
499
- ``right`` -- An instance of :class:~`fourier_expansion_framework.monoidpowerseries.EquivariantMonoidPowerSeries_abstract`.
500
501
EXAMPLES:
502
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import *
503
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *
504
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *
505
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *
506
sage: emps = EquivariantMonoidPowerSeriesRing( NNMonoid(), TrivialCharacterMonoid("1", QQ), TrivialRepresentation("1", QQ) )
507
sage: e = EquivariantMonoidPowerSeries(emps, {emps.characters().one_element() : { 1 : 1}}, emps.action().filter_all())
508
sage: EquivariantMonoidPowerSeries_LazyMultiplication(e, e).coefficients() # indirect doctest
509
{0: 0, 1: 0, 2: 1}
510
"""
511
# TODO: Insert coercing
512
if not isinstance(left.parent(), EquivariantMonoidPowerSeriesAmbient_abstract) \
513
or not isinstance(right.parent(), EquivariantMonoidPowerSeriesAmbient_abstract) :
514
raise TypeError, "both factors must be power series"
515
516
if left.parent() != right.parent() :
517
if left.parent() is right.parent().base_ring() :
518
parent = right.parent()
519
elif left.parent().base_ring() is right.parent() :
520
parent = left.parent()
521
522
raise ValueError, "incorrect parents of the factors"
523
else :
524
parent = left.parent()
525
526
coefficients_factory = \
527
EquivariantMonoidPowerseries_MultiplicationDelayedFactory( left, right )
528
529
precision = min(left.precision(), right.precision())
530
bounding_precision = None
531
if precision.is_infinite() :
532
left_coefficients = left.coefficients(True)
533
right_coefficients = right.coefficients(True)
534
535
left_keys = reduce(union, (set(c) for c in left_coefficients.itervalues()), set())
536
right_keys = reduce(union, (set(c) for c in right_coefficients.itervalues()), set())
537
538
bounding_precision = left.parent().action(). \
539
minimal_composition_filter(left_keys, right_keys)
540
541
return EquivariantMonoidPowerSeries_lazy( parent,
542
precision,
543
coefficients_factory.getcoeff,
544
bounding_precision = bounding_precision )
545
546