hilbert-modular-group 0.1.3__cp312-cp312-macosx_15_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of hilbert-modular-group might be problematic. Click here for more details.
- hilbert_modgroup/__init__.py +1 -0
- hilbert_modgroup/all.py +9 -0
- hilbert_modgroup/hilbert_modular_group_class.py +987 -0
- hilbert_modgroup/hilbert_modular_group_element.cpython-312-darwin.so +0 -0
- hilbert_modgroup/hilbert_modular_group_element.pyx +623 -0
- hilbert_modgroup/pullback.py +2256 -0
- hilbert_modgroup/pullback_cython.cpython-312-darwin.so +0 -0
- hilbert_modgroup/pullback_cython.pyx +411 -0
- hilbert_modgroup/upper_half_plane.cpython-312-darwin.so +0 -0
- hilbert_modgroup/upper_half_plane.pxd +59 -0
- hilbert_modgroup/upper_half_plane.pyx +1828 -0
- hilbert_modgroup/utils.py +66 -0
- hilbert_modgroup/version.py +21 -0
- hilbert_modular_group-0.1.3.dist-info/METADATA +891 -0
- hilbert_modular_group-0.1.3.dist-info/RECORD +18 -0
- hilbert_modular_group-0.1.3.dist-info/WHEEL +5 -0
- hilbert_modular_group-0.1.3.dist-info/licenses/LICENSE +674 -0
- hilbert_modular_group-0.1.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1828 @@
|
|
|
1
|
+
#cython: language_level=3
|
|
2
|
+
#cython: debug=True
|
|
3
|
+
r"""
|
|
4
|
+
|
|
5
|
+
Elements in the upper half plane of degree n
|
|
6
|
+
|
|
7
|
+
Note: The structure of this class is based on ArithmeticSubgroupElement from sage/modular/arithgroup/arithgroup_element.pyx
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
import sage
|
|
11
|
+
from .utils import get_prec
|
|
12
|
+
from sage.groups.perm_gps.permgroup_element import PermutationGroupElement
|
|
13
|
+
from sage.rings.real_mpfr import RealField
|
|
14
|
+
from sage.structure.element cimport Element, Vector
|
|
15
|
+
from sage.rings.integer import Integer
|
|
16
|
+
from sage.rings.cc import CC
|
|
17
|
+
from sage.rings.infinity import Infinity
|
|
18
|
+
from sage.structure.parent import Parent
|
|
19
|
+
from sage.structure.element cimport parent
|
|
20
|
+
|
|
21
|
+
from sage.rings.complex_mpfr cimport ComplexNumber
|
|
22
|
+
from sage.rings.complex_mpc cimport MPComplexNumber, MPComplexField_class
|
|
23
|
+
from sage.rings.complex_mpc import MPComplexField
|
|
24
|
+
from cpython.object cimport Py_EQ, Py_NE
|
|
25
|
+
from sage.modules.free_module_element import vector
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# Constructors for products Complex planes and upper half-planes
|
|
29
|
+
def ComplexPlaneProduct(degree, **kwds):
|
|
30
|
+
r"""
|
|
31
|
+
Construct a product of complex planes.
|
|
32
|
+
|
|
33
|
+
INPUT:
|
|
34
|
+
|
|
35
|
+
- `degree` - integer
|
|
36
|
+
|
|
37
|
+
EXAMPLES::
|
|
38
|
+
|
|
39
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct
|
|
40
|
+
sage: ComplexPlaneProduct(2)
|
|
41
|
+
Product of complex planes of degree 2
|
|
42
|
+
sage: ComplexPlaneProduct(3)
|
|
43
|
+
Product of complex planes of degree 3
|
|
44
|
+
|
|
45
|
+
"""
|
|
46
|
+
if isinstance(degree, sage.rings.number_field.number_field_base.NumberField):
|
|
47
|
+
degree = degree.absolute_degree()
|
|
48
|
+
return ComplexPlaneProduct__class(degree, **kwds)
|
|
49
|
+
|
|
50
|
+
def UpperHalfPlaneProduct(degree, **kwds):
|
|
51
|
+
r"""
|
|
52
|
+
Construct a product of complex planes.
|
|
53
|
+
|
|
54
|
+
INPUT:
|
|
55
|
+
|
|
56
|
+
- `degree` - integer
|
|
57
|
+
|
|
58
|
+
EXAMPLES::
|
|
59
|
+
|
|
60
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProduct
|
|
61
|
+
sage: UpperHalfPlaneProduct(2)
|
|
62
|
+
Product of upper half-planes of degree 2
|
|
63
|
+
sage: UpperHalfPlaneProduct(3)
|
|
64
|
+
Product of upper half-planes of degree 3
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
if isinstance(degree, sage.rings.number_field.number_field_base.NumberField):
|
|
68
|
+
degree = degree.absolute_degree()
|
|
69
|
+
return UpperHalfPlaneProduct__class(degree, **kwds)
|
|
70
|
+
|
|
71
|
+
## Constructors for elements of products of complex planes and upper half-planes
|
|
72
|
+
def UpperHalfPlaneProductElement(z, **kwds):
|
|
73
|
+
"""
|
|
74
|
+
Construct an element in the product of upper half planes.
|
|
75
|
+
|
|
76
|
+
INPUT:
|
|
77
|
+
|
|
78
|
+
- ``z`` -- input to construct a tuple of complex number
|
|
79
|
+
- ``kwds`` -- dict.
|
|
80
|
+
- ``degree`` -- positive integer. If a scalar input is given this is the degree of the constructed element.
|
|
81
|
+
|
|
82
|
+
OUTPUT:
|
|
83
|
+
- Element of the type UpperHalfPlaneProductElement__class
|
|
84
|
+
|
|
85
|
+
EXAMPLES::
|
|
86
|
+
|
|
87
|
+
sage: from hilbert_modgroup.all import UpperHalfPlaneProductElement
|
|
88
|
+
sage: UpperHalfPlaneProductElement([1+I,1+I])
|
|
89
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
90
|
+
sage: set(UpperHalfPlaneProductElement([1+I]*10))
|
|
91
|
+
{1.00000000000000 + 1.00000000000000*I}
|
|
92
|
+
sage: len(UpperHalfPlaneProductElement([1+I]*10))
|
|
93
|
+
10
|
|
94
|
+
sage: UpperHalfPlaneProductElement([1,1-I])
|
|
95
|
+
Traceback (most recent call last):
|
|
96
|
+
...
|
|
97
|
+
ValueError: Point [1.00000000000000, 1.00000000000000 - 1.00000000000000*I] not in upper half-plane!
|
|
98
|
+
sage: CF = ComplexField(103)
|
|
99
|
+
sage: z= UpperHalfPlaneProductElement([CF(0.25, 0.25),CF(1,1)])
|
|
100
|
+
sage: z[0]
|
|
101
|
+
0.250000000000000000000000000000 + 0.250000000000000000000000000000*I
|
|
102
|
+
"""
|
|
103
|
+
if isinstance(z,UpperHalfPlaneProductElement__class):
|
|
104
|
+
parent = kwds.get('parent')
|
|
105
|
+
if parent is z.parent():
|
|
106
|
+
return z
|
|
107
|
+
if parent:
|
|
108
|
+
return UpperHalfPlaneProductElement__class(list(z), parent=parent)
|
|
109
|
+
return z
|
|
110
|
+
prec = get_prec(z, **kwds)
|
|
111
|
+
if hasattr(z,'value'):
|
|
112
|
+
z = z.value()
|
|
113
|
+
if isinstance(z, sage.rings.number_field.number_field_element.NumberFieldElement):
|
|
114
|
+
z = z.complex_embeddings(prec)
|
|
115
|
+
if isinstance(z,list) and not isinstance(z[0], (ComplexNumber, MPComplexNumber)):
|
|
116
|
+
z = [MPComplexField(prec)(x) for x in z]
|
|
117
|
+
elif not isinstance(z,list) and kwds.get('degree',0)>0:
|
|
118
|
+
z = [MPComplexField(prec)(z)]*kwds.get('degree')
|
|
119
|
+
if 'parent' not in kwds:
|
|
120
|
+
kwds['parent'] = UpperHalfPlaneProduct(degree=len(z),prec=prec)
|
|
121
|
+
return UpperHalfPlaneProductElement__class(z,**kwds)
|
|
122
|
+
|
|
123
|
+
def ComplexPlaneProductElement(z,**kwds):
|
|
124
|
+
"""
|
|
125
|
+
Construct an element in the product of complex planes.
|
|
126
|
+
|
|
127
|
+
INPUT:
|
|
128
|
+
|
|
129
|
+
- ``z`` -- input to construct a tuple of complex number
|
|
130
|
+
- ``kwds`` -- dict.
|
|
131
|
+
- ``degree`` -- positive integer. If a scalar input is given this is the degree of the constructed element.
|
|
132
|
+
|
|
133
|
+
OUTPUT:
|
|
134
|
+
- Element of the type ComplexPlaneProductElement__class
|
|
135
|
+
|
|
136
|
+
EXAMPLES::
|
|
137
|
+
|
|
138
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
139
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(1,1)]); z
|
|
140
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
141
|
+
sage: a=QuadraticField(5).gen()
|
|
142
|
+
sage: ComplexPlaneProductElement(a)
|
|
143
|
+
[-2.23606797749979, 2.23606797749979]
|
|
144
|
+
sage: u0,u1=QuadraticField(5).unit_group().gens()
|
|
145
|
+
sage: ComplexPlaneProductElement(u0)
|
|
146
|
+
[-1.00000000000000, -1.00000000000000]
|
|
147
|
+
sage: ComplexPlaneProductElement(u1)
|
|
148
|
+
[1.61803398874989, -0.618033988749895]
|
|
149
|
+
sage: CF = ComplexField(103)
|
|
150
|
+
sage: z = [CF(1,0), CF(0,1)]
|
|
151
|
+
sage: ComplexPlaneProductElement(z)
|
|
152
|
+
[1.00000000000000000000000000000, 1.00000000000000000000000000000*I]
|
|
153
|
+
sage: ComplexPlaneProductElement(z).parent().prec()
|
|
154
|
+
103
|
|
155
|
+
"""
|
|
156
|
+
if isinstance(z,ComplexPlaneProductElement__class):
|
|
157
|
+
parent = kwds.get('parent')
|
|
158
|
+
if parent is z.parent():
|
|
159
|
+
return z
|
|
160
|
+
if parent:
|
|
161
|
+
return ComplexPlaneProductElement__class(list(z), parent=parent)
|
|
162
|
+
return z
|
|
163
|
+
# Get precision in the first hand from kwds, second from z and third set default to 53 bits
|
|
164
|
+
prec = get_prec(z, **kwds)
|
|
165
|
+
if isinstance(z, sage.rings.number_field.number_field_element.NumberFieldElement):
|
|
166
|
+
z = z.complex_embeddings(prec)
|
|
167
|
+
if hasattr(z,'value'):
|
|
168
|
+
z = z.value().complex_embeddings(prec)
|
|
169
|
+
if isinstance(z,list) and not isinstance(z[0],(ComplexNumber,MPComplexNumber)):
|
|
170
|
+
prec = kwds.get('prec', getattr(z[0], 'prec', lambda: 53)())
|
|
171
|
+
z = [MPComplexField(prec)(x) for x in z]
|
|
172
|
+
elif not isinstance(z,list) and kwds.get('degree',0)>0:
|
|
173
|
+
z = [MPComplexField(prec)(z)]*kwds.get('degree')
|
|
174
|
+
if 'parent' not in kwds:
|
|
175
|
+
kwds['parent'] = ComplexPlaneProduct(degree=len(z), prec=prec)
|
|
176
|
+
return ComplexPlaneProductElement__class(z,**kwds)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
cdef class ComplexPlaneProduct__class(Parent):
|
|
180
|
+
|
|
181
|
+
Element = ComplexPlaneProductElement__class
|
|
182
|
+
|
|
183
|
+
def __init__(self,degree, **kwds):
|
|
184
|
+
r"""
|
|
185
|
+
Class for a product of complex planes
|
|
186
|
+
|
|
187
|
+
EXAMPLES::
|
|
188
|
+
|
|
189
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct__class
|
|
190
|
+
sage: ComplexPlaneProduct__class(2)
|
|
191
|
+
Product of complex planes of degree 2
|
|
192
|
+
sage: TestSuite(ComplexPlaneProduct__class(2)).run()
|
|
193
|
+
|
|
194
|
+
"""
|
|
195
|
+
Parent.__init__(self)
|
|
196
|
+
self._degree = degree
|
|
197
|
+
self._prec = kwds.get('prec', 53)
|
|
198
|
+
|
|
199
|
+
def __hash__(self):
|
|
200
|
+
"""
|
|
201
|
+
Return hash of self.
|
|
202
|
+
|
|
203
|
+
EXAMPLES::
|
|
204
|
+
|
|
205
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct
|
|
206
|
+
sage: hash(ComplexPlaneProduct(2)) == hash('Product of complex planes of degree 2')
|
|
207
|
+
True
|
|
208
|
+
|
|
209
|
+
"""
|
|
210
|
+
return hash(str(self))
|
|
211
|
+
|
|
212
|
+
def construction(self):
|
|
213
|
+
r"""
|
|
214
|
+
No functor exists here but this needs to be defined for coercion to work properly.
|
|
215
|
+
|
|
216
|
+
EXAMPLES::
|
|
217
|
+
|
|
218
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct
|
|
219
|
+
sage: ComplexPlaneProduct(2).construction() is None
|
|
220
|
+
True
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
"""
|
|
224
|
+
return None
|
|
225
|
+
|
|
226
|
+
cpdef _coerce_map_from_(self, S):
|
|
227
|
+
r"""
|
|
228
|
+
Coerce maps from S to self.
|
|
229
|
+
|
|
230
|
+
EXAMPLES::
|
|
231
|
+
|
|
232
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct
|
|
233
|
+
sage: H=ComplexPlaneProduct(2)
|
|
234
|
+
sage: H._coerce_map_from_(ZZ)
|
|
235
|
+
Generic map:
|
|
236
|
+
From: Integer Ring
|
|
237
|
+
To: Product of complex planes of degree 2
|
|
238
|
+
sage: H._coerce_map_from_(QuadraticField(5))
|
|
239
|
+
Generic map:
|
|
240
|
+
From: Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?
|
|
241
|
+
To: Product of complex planes of degree 2
|
|
242
|
+
sage: H._coerce_map_from_(QuadraticField(5))(QuadraticField(5)(1))
|
|
243
|
+
[1.00000000000000, 1.00000000000000]
|
|
244
|
+
"""
|
|
245
|
+
if self._coerce_from_hash is None:
|
|
246
|
+
self.init_coerce(False)
|
|
247
|
+
if type(S) == type(self) and S.degree() == self.degree():
|
|
248
|
+
from sage.categories.homset import Hom
|
|
249
|
+
morphism = Hom(self, self).identity()
|
|
250
|
+
morphism._is_coercion = True
|
|
251
|
+
self._coerce_from_hash.set(S, morphism)
|
|
252
|
+
return morphism
|
|
253
|
+
if type(S) == type(self):
|
|
254
|
+
msg = f"Can not coerce UpperHalfPlaneProduct of degree {S.degree()} to degree {self.degree()}"
|
|
255
|
+
raise TypeError(msg)
|
|
256
|
+
try:
|
|
257
|
+
morphism = AnytoCPP(S,self)
|
|
258
|
+
self._coerce_from_hash.set(S, morphism)
|
|
259
|
+
return morphism
|
|
260
|
+
except:
|
|
261
|
+
pass
|
|
262
|
+
return super(ComplexPlaneProduct__class,self)._internal_coerce_map_from(S)
|
|
263
|
+
|
|
264
|
+
def _an_element_(self):
|
|
265
|
+
r"""
|
|
266
|
+
Create a typical element of self.
|
|
267
|
+
|
|
268
|
+
EXAMPLES::
|
|
269
|
+
|
|
270
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct
|
|
271
|
+
sage: ComplexPlaneProduct(2)._an_element_()
|
|
272
|
+
[ - 1.00000000000000*I, - 1.00000000000000*I]
|
|
273
|
+
|
|
274
|
+
"""
|
|
275
|
+
return self._element_constructor_([CC(0,-1)]*self.degree())
|
|
276
|
+
|
|
277
|
+
def __eq__(self, other):
|
|
278
|
+
r"""
|
|
279
|
+
Check if self is equal to other
|
|
280
|
+
|
|
281
|
+
EXAMPLES::
|
|
282
|
+
|
|
283
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct
|
|
284
|
+
sage: ComplexPlaneProduct(2) == ComplexPlaneProduct(2)
|
|
285
|
+
True
|
|
286
|
+
sage: ComplexPlaneProduct(2) == ComplexPlaneProduct(3)
|
|
287
|
+
False
|
|
288
|
+
|
|
289
|
+
"""
|
|
290
|
+
if not isinstance(other,type(self)):
|
|
291
|
+
return False
|
|
292
|
+
return self.degree() == other.degree()
|
|
293
|
+
|
|
294
|
+
def __str__(self):
|
|
295
|
+
r"""
|
|
296
|
+
String representation of self.
|
|
297
|
+
|
|
298
|
+
EXAMPLES::
|
|
299
|
+
|
|
300
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct__class
|
|
301
|
+
sage: ComplexPlaneProduct__class(2)
|
|
302
|
+
Product of complex planes of degree 2
|
|
303
|
+
|
|
304
|
+
"""
|
|
305
|
+
return f"Product of complex planes of degree {self._degree}"
|
|
306
|
+
|
|
307
|
+
def __repr__(self):
|
|
308
|
+
"""
|
|
309
|
+
Representation of self.
|
|
310
|
+
|
|
311
|
+
EXAMPLES::
|
|
312
|
+
|
|
313
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct__class
|
|
314
|
+
sage: ComplexPlaneProduct__class(2)
|
|
315
|
+
Product of complex planes of degree 2
|
|
316
|
+
|
|
317
|
+
"""
|
|
318
|
+
return str(self)
|
|
319
|
+
|
|
320
|
+
def __reduce__(self):
|
|
321
|
+
r"""
|
|
322
|
+
Prepare self for pickling
|
|
323
|
+
|
|
324
|
+
TESTS::
|
|
325
|
+
|
|
326
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct
|
|
327
|
+
sage: c = ComplexPlaneProduct(2)
|
|
328
|
+
sage: loads(dumps(c)) == c
|
|
329
|
+
True
|
|
330
|
+
|
|
331
|
+
"""
|
|
332
|
+
return ComplexPlaneProduct, (self.degree(),)
|
|
333
|
+
|
|
334
|
+
def degree(self):
|
|
335
|
+
r"""
|
|
336
|
+
Return the degree of this product of complex planes.
|
|
337
|
+
|
|
338
|
+
EXAMPLES::
|
|
339
|
+
|
|
340
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct
|
|
341
|
+
sage: ComplexPlaneProduct(2).degree()
|
|
342
|
+
2
|
|
343
|
+
sage: ComplexPlaneProduct(3).degree()
|
|
344
|
+
3
|
|
345
|
+
|
|
346
|
+
"""
|
|
347
|
+
return self._degree
|
|
348
|
+
|
|
349
|
+
def prec(self):
|
|
350
|
+
r"""
|
|
351
|
+
Return the precision of this product of complex planes.
|
|
352
|
+
|
|
353
|
+
EXAMPLES::
|
|
354
|
+
|
|
355
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProduct
|
|
356
|
+
sage: ComplexPlaneProduct(2).prec()
|
|
357
|
+
53
|
|
358
|
+
sage: ComplexPlaneProduct(3, prec=103).prec()
|
|
359
|
+
103
|
|
360
|
+
"""
|
|
361
|
+
return self._prec
|
|
362
|
+
|
|
363
|
+
def _element_constructor_(self,z, **kwds):
|
|
364
|
+
r"""
|
|
365
|
+
|
|
366
|
+
EXAMPLES::
|
|
367
|
+
|
|
368
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProduct
|
|
369
|
+
sage: ComplexPlaneProduct(degree=2)._element_constructor_([1,1])
|
|
370
|
+
[1.00000000000000, 1.00000000000000]
|
|
371
|
+
sage: ComplexPlaneProduct(degree=2)._element_constructor_([1,1+I])
|
|
372
|
+
[1.00000000000000, 1.00000000000000 + 1.00000000000000*I]
|
|
373
|
+
sage: F=QuadraticField(5)
|
|
374
|
+
sage: ComplexPlaneProduct(2,prec=103)(F(1))
|
|
375
|
+
[1.00000000000000000000000000000, 1.00000000000000000000000000000]
|
|
376
|
+
|
|
377
|
+
"""
|
|
378
|
+
kwds['degree'] = self.degree()
|
|
379
|
+
kwds['parent'] = self
|
|
380
|
+
kwds['prec'] = self._prec
|
|
381
|
+
return ComplexPlaneProductElement(z, **kwds)
|
|
382
|
+
|
|
383
|
+
cpdef coerce(self, x):
|
|
384
|
+
r"""
|
|
385
|
+
Coerce x to an element of self.
|
|
386
|
+
|
|
387
|
+
EXAMPLES::
|
|
388
|
+
|
|
389
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProduct
|
|
390
|
+
sage: ComplexPlaneProduct(degree=2).coerce([1,1])
|
|
391
|
+
[1.00000000000000, 1.00000000000000]
|
|
392
|
+
sage: ComplexPlaneProduct(degree=2).coerce([1,1+I])
|
|
393
|
+
[1.00000000000000, 1.00000000000000 + 1.00000000000000*I]
|
|
394
|
+
|
|
395
|
+
"""
|
|
396
|
+
return self._element_constructor_(x)
|
|
397
|
+
|
|
398
|
+
from sage.categories.map cimport Map
|
|
399
|
+
cdef class AnytoCPP(Map):
|
|
400
|
+
"""
|
|
401
|
+
Maps from 'anything' into the class ComplexPlaneProduct
|
|
402
|
+
|
|
403
|
+
TODO: implement this as a combination of maps from elements to complex numbers and then to lists.
|
|
404
|
+
|
|
405
|
+
"""
|
|
406
|
+
cpdef Element _call_(self, x):
|
|
407
|
+
"""
|
|
408
|
+
|
|
409
|
+
EXAMPLES::
|
|
410
|
+
|
|
411
|
+
sage: from hilbert_modgroup.upper_half_plane import AnytoCPP, ComplexPlaneProduct
|
|
412
|
+
sage: H = ComplexPlaneProduct(2)
|
|
413
|
+
sage: AnytoCPP(ZZ,H)
|
|
414
|
+
Generic map:
|
|
415
|
+
From: Integer Ring
|
|
416
|
+
To: Product of complex planes of degree 2
|
|
417
|
+
sage: AnytoCPP(ZZ,H)(1)
|
|
418
|
+
[1.00000000000000, 1.00000000000000]
|
|
419
|
+
sage: AnytoCPP(CC,H)
|
|
420
|
+
Generic map:
|
|
421
|
+
From: Complex Field with 53 bits of precision
|
|
422
|
+
To: Product of complex planes of degree 2
|
|
423
|
+
sage: AnytoCPP(CC,H)(CC(1,1))
|
|
424
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
425
|
+
sage: AnytoCPP(str,H)("1")
|
|
426
|
+
[1.00000000000000, 1.00000000000000]
|
|
427
|
+
sage: AnytoCPP(str,H)("a")
|
|
428
|
+
Traceback (most recent call last):
|
|
429
|
+
...
|
|
430
|
+
TypeError: unable to convert 'a' to a MPComplexNumber
|
|
431
|
+
"""
|
|
432
|
+
cdef ComplexPlaneProduct__class parent = <ComplexPlaneProduct__class>self._codomain
|
|
433
|
+
return parent._element_constructor(x)
|
|
434
|
+
|
|
435
|
+
def section(self):
|
|
436
|
+
"""
|
|
437
|
+
EXAMPLES::
|
|
438
|
+
|
|
439
|
+
sage: from sage.rings.real_mpfr import RRtoRR
|
|
440
|
+
sage: R10 = RealField(10)
|
|
441
|
+
sage: R100 = RealField(100)
|
|
442
|
+
sage: f = RRtoRR(R100, R10)
|
|
443
|
+
sage: f.section()
|
|
444
|
+
Generic map:
|
|
445
|
+
From: Real Field with 10 bits of precision
|
|
446
|
+
To: Real Field with 100 bits of precision
|
|
447
|
+
"""
|
|
448
|
+
return AnytoCPP(self._codomain, self.domain())
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
cdef class UpperHalfPlaneProduct__class(ComplexPlaneProduct__class):
|
|
452
|
+
r"""
|
|
453
|
+
Class for elements in a product of upper half-planes including the boundary (i.e. imaginary part >=0).
|
|
454
|
+
|
|
455
|
+
EXAMPLES::
|
|
456
|
+
|
|
457
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProduct__class
|
|
458
|
+
sage: UpperHalfPlaneProduct__class(2)
|
|
459
|
+
Product of upper half-planes of degree 2
|
|
460
|
+
sage: TestSuite(UpperHalfPlaneProduct__class(2)).run()
|
|
461
|
+
|
|
462
|
+
"""
|
|
463
|
+
Element = UpperHalfPlaneProductElement__class
|
|
464
|
+
|
|
465
|
+
def _element_constructor_(self,z, **kwds):
|
|
466
|
+
r"""
|
|
467
|
+
Construct an element of self.
|
|
468
|
+
|
|
469
|
+
EXAMPLES::
|
|
470
|
+
|
|
471
|
+
sage: from hilbert_modgroup.all import UpperHalfPlaneProduct
|
|
472
|
+
sage: UpperHalfPlaneProduct(degree=2)._element_constructor_([1,1-I])
|
|
473
|
+
Traceback (most recent call last):
|
|
474
|
+
...
|
|
475
|
+
ValueError: Point [1.00000000000000, 1.00000000000000 - 1.00000000000000*I] not in upper half-plane!
|
|
476
|
+
sage: UpperHalfPlaneProduct(degree=2)._element_constructor_([1+I,1+2*I])
|
|
477
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 2.00000000000000*I]
|
|
478
|
+
sage: F=QuadraticField(5)
|
|
479
|
+
sage: UpperHalfPlaneProduct(2,prec=103)(F(1))
|
|
480
|
+
[1.00000000000000000000000000000, 1.00000000000000000000000000000]
|
|
481
|
+
|
|
482
|
+
"""
|
|
483
|
+
kwds['degree'] = self.degree()
|
|
484
|
+
kwds['parent'] = self
|
|
485
|
+
kwds['prec'] = self._prec
|
|
486
|
+
return UpperHalfPlaneProductElement(z, **kwds)
|
|
487
|
+
|
|
488
|
+
def _an_element_(self):
|
|
489
|
+
r"""
|
|
490
|
+
Create a typical element of self.
|
|
491
|
+
|
|
492
|
+
EXAMPLES::
|
|
493
|
+
|
|
494
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProduct
|
|
495
|
+
sage: UpperHalfPlaneProduct(2)._an_element_()
|
|
496
|
+
[1.00000000000000*I, 1.00000000000000*I]
|
|
497
|
+
|
|
498
|
+
"""
|
|
499
|
+
return self._element_constructor_([CC(0.0,1.0)]*self.degree())
|
|
500
|
+
|
|
501
|
+
def __str__(self):
|
|
502
|
+
r"""
|
|
503
|
+
String representation of self.
|
|
504
|
+
|
|
505
|
+
EXAMPLES::
|
|
506
|
+
|
|
507
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProduct__class
|
|
508
|
+
sage: UpperHalfPlaneProduct__class(2)
|
|
509
|
+
Product of upper half-planes of degree 2
|
|
510
|
+
|
|
511
|
+
"""
|
|
512
|
+
return f"Product of upper half-planes of degree {self.degree()}"
|
|
513
|
+
|
|
514
|
+
def __repr__(self):
|
|
515
|
+
"""
|
|
516
|
+
Representation of self.
|
|
517
|
+
|
|
518
|
+
EXAMPLES::
|
|
519
|
+
|
|
520
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProduct__class
|
|
521
|
+
sage: UpperHalfPlaneProduct__class(2)
|
|
522
|
+
Product of upper half-planes of degree 2
|
|
523
|
+
|
|
524
|
+
"""
|
|
525
|
+
return str(self)
|
|
526
|
+
|
|
527
|
+
def __reduce__(self):
|
|
528
|
+
r"""
|
|
529
|
+
Prepare self for pickling
|
|
530
|
+
|
|
531
|
+
TESTS::
|
|
532
|
+
|
|
533
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProduct
|
|
534
|
+
sage: c = UpperHalfPlaneProduct(2)
|
|
535
|
+
sage: loads(dumps(c)) == c
|
|
536
|
+
True
|
|
537
|
+
|
|
538
|
+
"""
|
|
539
|
+
return UpperHalfPlaneProduct, (self.degree(),)
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
cdef class ComplexPlaneProductElement__class(Element):
|
|
543
|
+
r"""
|
|
544
|
+
Class of elements in products of complex planes
|
|
545
|
+
with additional ring structure given by:
|
|
546
|
+
- component-wise multiplication and division
|
|
547
|
+
- multiplication and division by elements of a number field of the same degree as the dimension.
|
|
548
|
+
|
|
549
|
+
EXAMPLES::
|
|
550
|
+
|
|
551
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProductElement__class
|
|
552
|
+
sage: z=ComplexPlaneProductElement__class([CC(1,1),CC(1,1)]); z
|
|
553
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
554
|
+
sage: z.parent()
|
|
555
|
+
Product of complex planes of degree 2
|
|
556
|
+
sage: TestSuite(z).run()
|
|
557
|
+
sage: a=QuadraticField(5).gen()
|
|
558
|
+
sage: ComplexPlaneProductElement__class(a.complex_embeddings())
|
|
559
|
+
[-2.23606797749979, 2.23606797749979]
|
|
560
|
+
sage: u0,u1=QuadraticField(5).unit_group().gens()
|
|
561
|
+
sage: u0 = QuadraticField(5)(u0)
|
|
562
|
+
sage: u1 = QuadraticField(5)(u1)
|
|
563
|
+
sage: ComplexPlaneProductElement__class(u0.complex_embeddings())
|
|
564
|
+
[-1.00000000000000, -1.00000000000000]
|
|
565
|
+
sage: ComplexPlaneProductElement__class(u1.complex_embeddings())
|
|
566
|
+
[1.61803398874989, -0.618033988749895]
|
|
567
|
+
|
|
568
|
+
TODO: Inherit from Ring or something? (for speed probably NO!)
|
|
569
|
+
|
|
570
|
+
"""
|
|
571
|
+
|
|
572
|
+
Parent = ComplexPlaneProduct__class
|
|
573
|
+
|
|
574
|
+
def __init__(self,zl, verbose=0, *argv, **kwds):
|
|
575
|
+
r"""
|
|
576
|
+
Init self from a list of complex numbers.
|
|
577
|
+
Currently, we only work with double (53 bits) precision.
|
|
578
|
+
|
|
579
|
+
INPUT:
|
|
580
|
+
|
|
581
|
+
- `zl` (list) - list of complex numbers
|
|
582
|
+
|
|
583
|
+
EXAMPLES:
|
|
584
|
+
|
|
585
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProductElement__class
|
|
586
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProduct,ComplexPlaneProductElement
|
|
587
|
+
sage: z=ComplexPlaneProductElement__class([CC(1,1),CC(2,3)]); z
|
|
588
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
589
|
+
sage: H=ComplexPlaneProduct(degree=2)
|
|
590
|
+
sage: ComplexPlaneProductElement([1,2,3],parent=H)
|
|
591
|
+
Traceback (most recent call last):
|
|
592
|
+
...
|
|
593
|
+
ValueError: Can not construct an element of degree 2 from list of length 3
|
|
594
|
+
"""
|
|
595
|
+
self._verbose = verbose
|
|
596
|
+
if verbose>0:
|
|
597
|
+
print("in __init__")
|
|
598
|
+
if not isinstance(zl,list):
|
|
599
|
+
raise ValueError("Need a list to init")
|
|
600
|
+
parent = kwds.get('parent')
|
|
601
|
+
self._degree = len(zl)
|
|
602
|
+
if not parent:
|
|
603
|
+
parent = ComplexPlaneProduct(self._degree)
|
|
604
|
+
if self._degree != parent.degree():
|
|
605
|
+
msg = f"Can not construct an element of degree {parent.degree()} from list of length {len(zl)}"
|
|
606
|
+
raise ValueError(msg)
|
|
607
|
+
if not isinstance(zl[0],(MPComplexNumber,ComplexNumber)):
|
|
608
|
+
raise ValueError("Need a list of MPComplexNumber")
|
|
609
|
+
super().__init__(parent)
|
|
610
|
+
self._prec = zl[0].prec()
|
|
611
|
+
self._base_ring = MPComplexField(self._prec)
|
|
612
|
+
if verbose>0:
|
|
613
|
+
print(zl[0],type(zl[0]))
|
|
614
|
+
if isinstance(zl[0],ComplexNumber):
|
|
615
|
+
self._z = [self._base_ring(z) for z in zl]
|
|
616
|
+
else:
|
|
617
|
+
self._z = zl
|
|
618
|
+
self._x = [z.real() for z in zl]
|
|
619
|
+
self._y = [z.imag() for z in zl]
|
|
620
|
+
if all([x>=0 for x in self._y]):
|
|
621
|
+
self._is_in_upper_half_plane = True
|
|
622
|
+
else:
|
|
623
|
+
self._is_in_upper_half_plane = False
|
|
624
|
+
self._imag_norm = 0.0
|
|
625
|
+
self._real_norm = 0.0
|
|
626
|
+
self._norm = 0.0
|
|
627
|
+
self._abs_square_norm = 0.0
|
|
628
|
+
self._imag_norm_set = 0
|
|
629
|
+
self._real_norm_set = 0
|
|
630
|
+
self._norm_set = 0
|
|
631
|
+
self._abs_square_norm_set = 0
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
def _cache_key(self):
|
|
635
|
+
"""
|
|
636
|
+
Cache key for self.
|
|
637
|
+
|
|
638
|
+
EXAMPLES::
|
|
639
|
+
|
|
640
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProductElement__class
|
|
641
|
+
sage: z=ComplexPlaneProductElement__class([CC(1,1),CC(2,3)])
|
|
642
|
+
sage: z._cache_key()
|
|
643
|
+
('ComplexPlaneProductElement__class',
|
|
644
|
+
(1.00000000000000 + 1.00000000000000*I,
|
|
645
|
+
2.00000000000000 + 3.00000000000000*I))
|
|
646
|
+
|
|
647
|
+
"""
|
|
648
|
+
return (self.__class__.__name__,tuple(self._z))
|
|
649
|
+
|
|
650
|
+
def __reduce__(self):
|
|
651
|
+
r"""
|
|
652
|
+
Prepare self for pickling
|
|
653
|
+
|
|
654
|
+
TESTS::
|
|
655
|
+
|
|
656
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProductElement
|
|
657
|
+
sage: c = ComplexPlaneProductElement([1,1])
|
|
658
|
+
sage: loads(dumps(c)) == c
|
|
659
|
+
True
|
|
660
|
+
|
|
661
|
+
"""
|
|
662
|
+
return ComplexPlaneProductElement, (self.z(),)
|
|
663
|
+
|
|
664
|
+
def __hash__(self):
|
|
665
|
+
"""
|
|
666
|
+
Hash of self.
|
|
667
|
+
|
|
668
|
+
EXAMPLES::
|
|
669
|
+
|
|
670
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProductElement__class
|
|
671
|
+
sage: z=ComplexPlaneProductElement__class([CC(1,1),CC(2,3)])
|
|
672
|
+
sage: hash(z) # random
|
|
673
|
+
2592654998731023797
|
|
674
|
+
|
|
675
|
+
"""
|
|
676
|
+
return hash(self._cache_key())
|
|
677
|
+
|
|
678
|
+
cpdef z(self):
|
|
679
|
+
r"""
|
|
680
|
+
Return the list of complex numbers in this element.
|
|
681
|
+
|
|
682
|
+
EXAMPLES::
|
|
683
|
+
|
|
684
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement, UpperHalfPlaneProductElement
|
|
685
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)])
|
|
686
|
+
sage: z.z()
|
|
687
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
688
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
689
|
+
sage: z.z()
|
|
690
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
691
|
+
sage: z=UpperHalfPlaneProductElement([CC(1,1),CC(2,1)])
|
|
692
|
+
sage: z.z()
|
|
693
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 1.00000000000000*I]
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
"""
|
|
697
|
+
return self._z
|
|
698
|
+
|
|
699
|
+
def is_in_upper_half_plane(self):
|
|
700
|
+
"""
|
|
701
|
+
Return True if self is in the upper half plane or its boundary.
|
|
702
|
+
|
|
703
|
+
EXAMPLES::
|
|
704
|
+
|
|
705
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
706
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z
|
|
707
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
708
|
+
sage: z.is_in_upper_half_plane()
|
|
709
|
+
True
|
|
710
|
+
sage: z=ComplexPlaneProductElement([CC(1,0),CC(2,3)]); z
|
|
711
|
+
[1.00000000000000, 2.00000000000000 + 3.00000000000000*I]
|
|
712
|
+
sage: z.is_in_upper_half_plane()
|
|
713
|
+
True
|
|
714
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
715
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
716
|
+
sage: z.is_in_upper_half_plane()
|
|
717
|
+
False
|
|
718
|
+
|
|
719
|
+
"""
|
|
720
|
+
return bool(self._is_in_upper_half_plane)
|
|
721
|
+
|
|
722
|
+
def as_upper_half_plane_element(self):
|
|
723
|
+
r"""
|
|
724
|
+
Return a copy of self with type UpperHalfPlaneProductElement__class
|
|
725
|
+
|
|
726
|
+
EXAMPLES::
|
|
727
|
+
|
|
728
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
729
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z
|
|
730
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
731
|
+
sage: z.as_upper_half_plane_element()
|
|
732
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
733
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
734
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
735
|
+
sage: z.as_upper_half_plane_element()
|
|
736
|
+
Traceback (most recent call last):
|
|
737
|
+
...
|
|
738
|
+
ValueError: Can not convert self to element in product of upper half-planes.
|
|
739
|
+
"""
|
|
740
|
+
if not self.is_in_upper_half_plane():
|
|
741
|
+
raise ValueError("Can not convert self to element in product of upper half-planes.")
|
|
742
|
+
return UpperHalfPlaneProductElement(self._z)
|
|
743
|
+
|
|
744
|
+
def is_zero(self):
|
|
745
|
+
r"""
|
|
746
|
+
Return true if all components of self is zero
|
|
747
|
+
|
|
748
|
+
EXAMPLES:
|
|
749
|
+
|
|
750
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
751
|
+
sage: z=ComplexPlaneProductElement([CC(0,0),CC(0,0)])
|
|
752
|
+
sage: z.is_zero()
|
|
753
|
+
True
|
|
754
|
+
sage: z=ComplexPlaneProductElement([CC(0,0),CC(1,0)])
|
|
755
|
+
sage: z.is_zero()
|
|
756
|
+
False
|
|
757
|
+
sage: z=ComplexPlaneProductElement([CC(-1,0),CC(1,0)])
|
|
758
|
+
sage: z.is_zero()
|
|
759
|
+
False
|
|
760
|
+
"""
|
|
761
|
+
|
|
762
|
+
return all([x==0 for x in self])
|
|
763
|
+
|
|
764
|
+
def base_ring(self):
|
|
765
|
+
r"""
|
|
766
|
+
Base ring of self.
|
|
767
|
+
|
|
768
|
+
EXAMPLES::
|
|
769
|
+
|
|
770
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
771
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z
|
|
772
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
773
|
+
sage: z.base_ring()
|
|
774
|
+
Complex Field with 53 bits of precision
|
|
775
|
+
"""
|
|
776
|
+
return self._base_ring
|
|
777
|
+
|
|
778
|
+
cpdef prec(self):
|
|
779
|
+
r"""
|
|
780
|
+
The precision of self.
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
EXAMPLES::
|
|
784
|
+
|
|
785
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
786
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1),CC(4,2)])
|
|
787
|
+
sage: z.prec()
|
|
788
|
+
53
|
|
789
|
+
sage: z=ComplexPlaneProductElement([ComplexField(106)(1,1),ComplexField(106)(2,-1)])
|
|
790
|
+
sage: z.prec()
|
|
791
|
+
106
|
|
792
|
+
"""
|
|
793
|
+
return self._prec
|
|
794
|
+
|
|
795
|
+
def degree(self):
|
|
796
|
+
"""
|
|
797
|
+
Degree of self.
|
|
798
|
+
|
|
799
|
+
EXAMPLES::
|
|
800
|
+
|
|
801
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
802
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z
|
|
803
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
804
|
+
sage: z.degree()
|
|
805
|
+
2
|
|
806
|
+
|
|
807
|
+
"""
|
|
808
|
+
return self._degree
|
|
809
|
+
|
|
810
|
+
def __len__(self):
|
|
811
|
+
"""
|
|
812
|
+
Length of self.
|
|
813
|
+
|
|
814
|
+
EXAMPLES::
|
|
815
|
+
|
|
816
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
817
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
818
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
819
|
+
sage: len(z)
|
|
820
|
+
2
|
|
821
|
+
"""
|
|
822
|
+
return self.degree()
|
|
823
|
+
|
|
824
|
+
cpdef real(self):
|
|
825
|
+
"""
|
|
826
|
+
Real parts of self
|
|
827
|
+
|
|
828
|
+
EXAMPLES::
|
|
829
|
+
|
|
830
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
831
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z.real()
|
|
832
|
+
[1.00000000000000, 2.00000000000000]
|
|
833
|
+
|
|
834
|
+
"""
|
|
835
|
+
return self._x
|
|
836
|
+
|
|
837
|
+
cpdef imag(self):
|
|
838
|
+
"""
|
|
839
|
+
Imaginary parts of self
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
EXAMPLES::
|
|
843
|
+
|
|
844
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
845
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z.imag()
|
|
846
|
+
[1.00000000000000, 3.00000000000000]
|
|
847
|
+
"""
|
|
848
|
+
return self._y
|
|
849
|
+
|
|
850
|
+
cpdef __copy__(self):
|
|
851
|
+
"""
|
|
852
|
+
Copy self.
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
EXAMPLES::
|
|
856
|
+
|
|
857
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
858
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z
|
|
859
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
860
|
+
sage: w=copy(z); w
|
|
861
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
862
|
+
sage: w==z
|
|
863
|
+
True
|
|
864
|
+
"""
|
|
865
|
+
return self.__class__(self._z, verbose=self._verbose)
|
|
866
|
+
|
|
867
|
+
def __repr__(self):
|
|
868
|
+
"""
|
|
869
|
+
String representation of self.
|
|
870
|
+
|
|
871
|
+
EXAMPLES::
|
|
872
|
+
|
|
873
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
874
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
875
|
+
sage: z
|
|
876
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
877
|
+
|
|
878
|
+
"""
|
|
879
|
+
return str(list(self))
|
|
880
|
+
|
|
881
|
+
def __getitem__(self,i):
|
|
882
|
+
"""
|
|
883
|
+
Get the items of self.
|
|
884
|
+
|
|
885
|
+
EXAMPLES::
|
|
886
|
+
|
|
887
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
888
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
889
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
890
|
+
sage: z[0]
|
|
891
|
+
1.00000000000000 + 1.00000000000000*I
|
|
892
|
+
sage: z[1]
|
|
893
|
+
2.00000000000000 - 1.00000000000000*I
|
|
894
|
+
"""
|
|
895
|
+
if isinstance(i, (int, Integer)) and 0 <= i < self._degree:
|
|
896
|
+
return self._z[i]
|
|
897
|
+
else:
|
|
898
|
+
raise IndexError
|
|
899
|
+
|
|
900
|
+
cpdef _is_equal(self, ComplexPlaneProductElement__class other):
|
|
901
|
+
"""
|
|
902
|
+
Return 1 if ``self`` is equal to ``other``
|
|
903
|
+
|
|
904
|
+
INPUT:
|
|
905
|
+
- ``other`` - Element of the type ``ComplexPlaneProductElement__class``
|
|
906
|
+
|
|
907
|
+
EXAMPLES::
|
|
908
|
+
|
|
909
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
910
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
911
|
+
sage: w1=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
912
|
+
sage: w2=ComplexPlaneProductElement([CC(1,1),CC(2,1)])
|
|
913
|
+
sage: z._is_equal(z)
|
|
914
|
+
1
|
|
915
|
+
sage: z._is_equal(w1)
|
|
916
|
+
1
|
|
917
|
+
sage: z._is_equal(w2)
|
|
918
|
+
0
|
|
919
|
+
|
|
920
|
+
"""
|
|
921
|
+
cdef int i
|
|
922
|
+
for i in range(self.degree()):
|
|
923
|
+
if self._x[i] != other._x[i] or self._y[i] != other._y[i]:
|
|
924
|
+
return 0
|
|
925
|
+
return 1
|
|
926
|
+
|
|
927
|
+
def __richcmp__(self, right, int op):
|
|
928
|
+
"""
|
|
929
|
+
Compare self with other
|
|
930
|
+
|
|
931
|
+
INPUT:
|
|
932
|
+
- `right`
|
|
933
|
+
- `op`
|
|
934
|
+
|
|
935
|
+
EXAMPLES::
|
|
936
|
+
|
|
937
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
938
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z
|
|
939
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
940
|
+
sage: w=copy(z); w
|
|
941
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
942
|
+
sage: w==z
|
|
943
|
+
True
|
|
944
|
+
sage: w!=z
|
|
945
|
+
False
|
|
946
|
+
sage: w>z
|
|
947
|
+
Traceback (most recent call last):
|
|
948
|
+
...
|
|
949
|
+
NotImplementedError: Ordering of points in H^n is not implemented!
|
|
950
|
+
"""
|
|
951
|
+
res=1
|
|
952
|
+
if op != Py_EQ and op != Py_NE:
|
|
953
|
+
raise NotImplementedError("Ordering of points in H^n is not implemented!")
|
|
954
|
+
if type(self) != type(right) or right.degree() != self.degree():
|
|
955
|
+
res=0
|
|
956
|
+
else:
|
|
957
|
+
res = self._is_equal(right)
|
|
958
|
+
if op == Py_NE:
|
|
959
|
+
res = 1 - res
|
|
960
|
+
return bool(res)
|
|
961
|
+
|
|
962
|
+
cpdef imag_norm(self):
|
|
963
|
+
"""
|
|
964
|
+
Return the product of all imaginary parts of self.
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
EXAMPLES::
|
|
968
|
+
|
|
969
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
970
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
971
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
972
|
+
sage: z.imag_norm()
|
|
973
|
+
-1.00000000000000
|
|
974
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(0,0)]); z
|
|
975
|
+
[1.00000000000000 + 1.00000000000000*I, 0]
|
|
976
|
+
sage: z.imag_norm()
|
|
977
|
+
0.000000000000000
|
|
978
|
+
"""
|
|
979
|
+
cdef int i
|
|
980
|
+
if self._imag_norm_set==0:
|
|
981
|
+
self._imag_norm=self.base_ring().base_ring()(1)
|
|
982
|
+
for i in range(self._degree):
|
|
983
|
+
self._imag_norm = self._imag_norm*self._y[i]
|
|
984
|
+
self._imag_norm_set=1
|
|
985
|
+
return self._imag_norm
|
|
986
|
+
|
|
987
|
+
cpdef abs(self):
|
|
988
|
+
"""
|
|
989
|
+
Return the element consisting of the absolute value of all elements.
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
EXAMPLES::
|
|
993
|
+
|
|
994
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
995
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
996
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
997
|
+
sage: z.abs() # abs tol 1e-10
|
|
998
|
+
[1.41421356237310, 2.23606797749979]
|
|
999
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(0,0)]); z
|
|
1000
|
+
[1.00000000000000 + 1.00000000000000*I, 0]
|
|
1001
|
+
sage: z.imag_norm()
|
|
1002
|
+
0.000000000000000
|
|
1003
|
+
"""
|
|
1004
|
+
return ComplexPlaneProductElement([abs(self._z[i]) for i in range(self._degree)])
|
|
1005
|
+
|
|
1006
|
+
cpdef abs_square_norm(self):
|
|
1007
|
+
r"""
|
|
1008
|
+
Return the norm of |z|^2
|
|
1009
|
+
|
|
1010
|
+
EXAMPLES::
|
|
1011
|
+
|
|
1012
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1013
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
1014
|
+
sage: z.abs_square_norm() # abs tol 1e-10
|
|
1015
|
+
10.0000000000000
|
|
1016
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(0,0)])
|
|
1017
|
+
sage: z.abs_square_norm() # abs tol 1e-10
|
|
1018
|
+
0.000000000000000
|
|
1019
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(1,0)])
|
|
1020
|
+
sage: z.abs_square_norm() # abs tol 1e-10
|
|
1021
|
+
2.000000000000000
|
|
1022
|
+
|
|
1023
|
+
"""
|
|
1024
|
+
cdef int i
|
|
1025
|
+
if not self._abs_square_norm_set:
|
|
1026
|
+
self._abs_square_norm = self.base_ring().base_ring()(1)
|
|
1027
|
+
for i in range(self._degree):
|
|
1028
|
+
self._abs_square_norm = self._abs_square_norm * (self._x[i]**2 + self._y[i]**2)
|
|
1029
|
+
self._abs_square_norm_set = 1
|
|
1030
|
+
return self._abs_square_norm
|
|
1031
|
+
|
|
1032
|
+
cpdef real_norm(self):
|
|
1033
|
+
"""
|
|
1034
|
+
Return the product of all real parts of self.
|
|
1035
|
+
|
|
1036
|
+
EXAMPLES::
|
|
1037
|
+
|
|
1038
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1039
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
1040
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1041
|
+
sage: z.real_norm()
|
|
1042
|
+
2.00000000000000
|
|
1043
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(0,0)]); z
|
|
1044
|
+
[1.00000000000000 + 1.00000000000000*I, 0]
|
|
1045
|
+
sage: z.real_norm()
|
|
1046
|
+
0.000000000000000
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
"""
|
|
1050
|
+
cdef int i
|
|
1051
|
+
if not self._real_norm_set:
|
|
1052
|
+
self._real_norm=self.base_ring().base_ring()(1)
|
|
1053
|
+
for i in range(self._degree):
|
|
1054
|
+
self._real_norm = self._real_norm*self._x[i]
|
|
1055
|
+
self._real_norm_set=1
|
|
1056
|
+
return self._real_norm
|
|
1057
|
+
|
|
1058
|
+
cpdef norm(self):
|
|
1059
|
+
"""
|
|
1060
|
+
Return the product of all components of self.
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
EXAMPLES::
|
|
1064
|
+
|
|
1065
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1066
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
1067
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1068
|
+
sage: z.norm()
|
|
1069
|
+
3.00000000000000 + 1.00000000000000*I
|
|
1070
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(0,0)]); z
|
|
1071
|
+
[1.00000000000000 + 1.00000000000000*I, 0]
|
|
1072
|
+
sage: z.norm()
|
|
1073
|
+
0
|
|
1074
|
+
sage: z=ComplexPlaneProductElement([ComplexField(106)(1,1),ComplexField(106)(2,-1)]); z
|
|
1075
|
+
[1.000000000000000000000000000000 + 1.000000000000000000000000000000*I, 2.000000000000000000000000000000 - 1.000000000000000000000000000000*I]
|
|
1076
|
+
sage: z.norm()
|
|
1077
|
+
3.000000000000000000000000000000 + 1.000000000000000000000000000000*I
|
|
1078
|
+
"""
|
|
1079
|
+
cdef int i
|
|
1080
|
+
if self._norm_set==0:
|
|
1081
|
+
self._norm = self.base_ring()(1)
|
|
1082
|
+
for i in range(self._degree):
|
|
1083
|
+
self._norm = self._norm*self._z[i]
|
|
1084
|
+
self._norm_set=1
|
|
1085
|
+
return self._norm
|
|
1086
|
+
|
|
1087
|
+
cpdef vector(self):
|
|
1088
|
+
r"""
|
|
1089
|
+
Return self as a vector
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
EXAMPLES::
|
|
1093
|
+
|
|
1094
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1095
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
1096
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1097
|
+
sage: z.vector()
|
|
1098
|
+
(1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I)
|
|
1099
|
+
sage: z=ComplexPlaneProductElement([ComplexField(106)(1,1),ComplexField(106)(2,-1)]); z
|
|
1100
|
+
[1.000000000000000000000000000000 + 1.000000000000000000000000000000*I, 2.000000000000000000000000000000 - 1.000000000000000000000000000000*I]
|
|
1101
|
+
sage: z.vector()
|
|
1102
|
+
(1.000000000000000000000000000000 + 1.000000000000000000000000000000*I, 2.000000000000000000000000000000 - 1.000000000000000000000000000000*I)
|
|
1103
|
+
sage: type(z.vector())
|
|
1104
|
+
<class 'sage.modules.free_module_element.FreeModuleElement_generic_dense'>
|
|
1105
|
+
sage: z.vector().base_ring()
|
|
1106
|
+
Complex Field with 106 bits of precision
|
|
1107
|
+
|
|
1108
|
+
"""
|
|
1109
|
+
return vector(self)
|
|
1110
|
+
|
|
1111
|
+
cpdef vector_norm(self,p=2):
|
|
1112
|
+
r"""
|
|
1113
|
+
Return the Euclidean norm of self as a vector in C^n
|
|
1114
|
+
|
|
1115
|
+
INPUT:
|
|
1116
|
+
- `p` (integer) default = 2 (L2-norm). Other options include =1 (L1-norm) or =0 (Infinity-norm)
|
|
1117
|
+
|
|
1118
|
+
Note: This is about twice as fast as doing z.vector().norm()
|
|
1119
|
+
|
|
1120
|
+
EXAMPLES::
|
|
1121
|
+
|
|
1122
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1123
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
1124
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1125
|
+
sage: z.vector_norm()
|
|
1126
|
+
2.64575131106459
|
|
1127
|
+
sage: z.vector_norm(Infinity)
|
|
1128
|
+
2.23606797749979
|
|
1129
|
+
sage: z.vector_norm(1)
|
|
1130
|
+
3.65028153987288
|
|
1131
|
+
sage: z.vector_norm() == z.vector().norm()
|
|
1132
|
+
True
|
|
1133
|
+
sage: z.vector_norm(5)
|
|
1134
|
+
2.27959492535969
|
|
1135
|
+
"""
|
|
1136
|
+
from sage.rings.infinity import infinity
|
|
1137
|
+
cdef int i
|
|
1138
|
+
if p == infinity:
|
|
1139
|
+
return max([abs(z) for z in self._z])
|
|
1140
|
+
p = self.base_ring().base_ring()(p)
|
|
1141
|
+
res = sum([abs(z)**p for z in self._z])
|
|
1142
|
+
if p != 1:
|
|
1143
|
+
res = res**(p**-1)
|
|
1144
|
+
return res
|
|
1145
|
+
|
|
1146
|
+
def change_ring(self,R):
|
|
1147
|
+
"""
|
|
1148
|
+
Change the base ring of self.
|
|
1149
|
+
|
|
1150
|
+
INPUT:
|
|
1151
|
+
- `R` -- MOComplexField
|
|
1152
|
+
|
|
1153
|
+
EXAMPLES::
|
|
1154
|
+
|
|
1155
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1156
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
1157
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1158
|
+
sage: z.change_ring(MPComplexField(106));z
|
|
1159
|
+
[1.000000000000000000000000000000 + 1.000000000000000000000000000000*I, 2.000000000000000000000000000000 - 1.000000000000000000000000000000*I]
|
|
1160
|
+
sage: z.change_ring(MPComplexField(22));z
|
|
1161
|
+
[1.00000 + 1.00000*I, 2.00000 - 1.00000*I]
|
|
1162
|
+
|
|
1163
|
+
"""
|
|
1164
|
+
if not isinstance(R,MPComplexField_class):
|
|
1165
|
+
raise ValueError(f"Can not coerce self into {R}")
|
|
1166
|
+
self.set_prec(R.prec())
|
|
1167
|
+
|
|
1168
|
+
cpdef set_prec(self,prec):
|
|
1169
|
+
"""
|
|
1170
|
+
Change the precision of self.
|
|
1171
|
+
|
|
1172
|
+
INPUT:
|
|
1173
|
+
- `prec`
|
|
1174
|
+
|
|
1175
|
+
EXAMPLES::
|
|
1176
|
+
|
|
1177
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1178
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
1179
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1180
|
+
sage: z.set_prec(106);z
|
|
1181
|
+
[1.000000000000000000000000000000 + 1.000000000000000000000000000000*I, 2.000000000000000000000000000000 - 1.000000000000000000000000000000*I]
|
|
1182
|
+
sage: z.set_prec(22);z
|
|
1183
|
+
[1.00000 + 1.00000*I, 2.00000 - 1.00000*I]
|
|
1184
|
+
|
|
1185
|
+
"""
|
|
1186
|
+
self._base_ring = MPComplexField(prec)
|
|
1187
|
+
self._z = [self._base_ring(z) for z in self]
|
|
1188
|
+
self._x = [self._base_ring.base_ring()(x) for x in self._x]
|
|
1189
|
+
self._y = [self._base_ring.base_ring()(y) for y in self._y]
|
|
1190
|
+
|
|
1191
|
+
@classmethod
|
|
1192
|
+
def _extract_left_right_parent(cls,left,right):
|
|
1193
|
+
"""
|
|
1194
|
+
Convert the argument left and right to elements of the type ComplexPlaneProduct_class
|
|
1195
|
+
|
|
1196
|
+
INPUT:
|
|
1197
|
+
|
|
1198
|
+
- ``left`` -- object
|
|
1199
|
+
- ``right`` -- object
|
|
1200
|
+
|
|
1201
|
+
EXAMPLES::
|
|
1202
|
+
|
|
1203
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProductElement,ComplexPlaneProductElement__class
|
|
1204
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
1205
|
+
sage: w=ComplexPlaneProductElement([CC(1,1),CC(2,1)])
|
|
1206
|
+
sage: ComplexPlaneProductElement__class._extract_left_right_parent(z,w)
|
|
1207
|
+
([1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I],
|
|
1208
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 1.00000000000000*I],
|
|
1209
|
+
Product of complex planes of degree 2)
|
|
1210
|
+
|
|
1211
|
+
"""
|
|
1212
|
+
if isinstance(left, ComplexPlaneProductElement__class):
|
|
1213
|
+
right = ComplexPlaneProductElement(right, prec=left.prec(), degree=left.degree())
|
|
1214
|
+
parent = left.parent()
|
|
1215
|
+
elif isinstance(right, ComplexPlaneProductElement__class):
|
|
1216
|
+
left = ComplexPlaneProductElement(left, prec=right.prec(), degree=right.degree())
|
|
1217
|
+
parent = right.parent()
|
|
1218
|
+
else:
|
|
1219
|
+
raise ValueError("One of left or right must be of the type ComplexPlaneProductElement__class!")
|
|
1220
|
+
return left,right,parent
|
|
1221
|
+
|
|
1222
|
+
cdef _add_(self, other):
|
|
1223
|
+
"""
|
|
1224
|
+
Add ``other`` to ``self`` and convert to ``parent``. Used by the ``__add__`` method.
|
|
1225
|
+
|
|
1226
|
+
EXAMPLES::
|
|
1227
|
+
|
|
1228
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProductElement,ComplexPlaneProductElement__class
|
|
1229
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProductElement__class
|
|
1230
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z
|
|
1231
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
1232
|
+
sage: w=ComplexPlaneProductElement([CC(2,2),CC(3,3)]); w
|
|
1233
|
+
[2.00000000000000 + 2.00000000000000*I, 3.00000000000000 + 3.00000000000000*I]
|
|
1234
|
+
sage: z+w
|
|
1235
|
+
[3.00000000000000 + 3.00000000000000*I, 5.00000000000000 + 6.00000000000000*I]
|
|
1236
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]); z
|
|
1237
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1238
|
+
sage: z+1
|
|
1239
|
+
[2.00000000000000 + 1.00000000000000*I, 3.00000000000000 - 1.00000000000000*I]
|
|
1240
|
+
sage: K=QuadraticField(5)
|
|
1241
|
+
sage: a=K.gen()
|
|
1242
|
+
sage: z+a
|
|
1243
|
+
[-1.23606797749979 + 1.00000000000000*I, 4.23606797749979 - 1.00000000000000*I]
|
|
1244
|
+
sage: a+z
|
|
1245
|
+
[-1.23606797749979 + 1.00000000000000*I, 4.23606797749979 - 1.00000000000000*I]
|
|
1246
|
+
sage: w=ComplexPlaneProductElement([CC(2,2),CC(3,3),CC(4,4)]); w
|
|
1247
|
+
[2.00000000000000 + 2.00000000000000*I, 3.00000000000000 + 3.00000000000000*I, 4.00000000000000 + 4.00000000000000*I]
|
|
1248
|
+
sage: z+w
|
|
1249
|
+
Traceback (most recent call last):
|
|
1250
|
+
...
|
|
1251
|
+
TypeError: unsupported operand parent(s) for +: 'Product of complex planes of degree 2' and 'Product of complex planes of degree 3'
|
|
1252
|
+
sage: from hilbert_modgroup.all import UpperHalfPlaneProduct
|
|
1253
|
+
sage: z=UpperHalfPlaneProduct(degree=2)([1+I,1+2*I]); z
|
|
1254
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 2.00000000000000*I]
|
|
1255
|
+
sage: z+2
|
|
1256
|
+
[3.00000000000000 + 1.00000000000000*I, 3.00000000000000 + 2.00000000000000*I]
|
|
1257
|
+
sage: 2+z
|
|
1258
|
+
[3.00000000000000 + 1.00000000000000*I, 3.00000000000000 + 2.00000000000000*I]
|
|
1259
|
+
sage: type(z+2) == type(z)
|
|
1260
|
+
True
|
|
1261
|
+
sage: type(2+z) == type(z)
|
|
1262
|
+
True
|
|
1263
|
+
|
|
1264
|
+
"""
|
|
1265
|
+
if self._degree != other.degree() or self._prec != other.prec():
|
|
1266
|
+
raise TypeError
|
|
1267
|
+
return self._parent([self._z[i] + other[i] for i in range(self.degree())])
|
|
1268
|
+
|
|
1269
|
+
cdef _neg_(self):
|
|
1270
|
+
"""
|
|
1271
|
+
Negative of self.
|
|
1272
|
+
|
|
1273
|
+
EXAMPLES::
|
|
1274
|
+
|
|
1275
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1276
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)])
|
|
1277
|
+
sage: -z
|
|
1278
|
+
[-1.00000000000000 - 1.00000000000000*I, -2.00000000000000 - 3.00000000000000*I]
|
|
1279
|
+
|
|
1280
|
+
"""
|
|
1281
|
+
return self._parent([-self._z[i] for i in range(self.degree())])
|
|
1282
|
+
|
|
1283
|
+
cdef _sub_(self,other):
|
|
1284
|
+
"""
|
|
1285
|
+
Subtract ``other`` from ``self``
|
|
1286
|
+
|
|
1287
|
+
EXAMPLES::
|
|
1288
|
+
|
|
1289
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1290
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,3)]); z
|
|
1291
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 3.00000000000000*I]
|
|
1292
|
+
sage: w=ComplexPlaneProductElement([CC(2,2),CC(3,3)]); w
|
|
1293
|
+
[2.00000000000000 + 2.00000000000000*I, 3.00000000000000 + 3.00000000000000*I]
|
|
1294
|
+
sage: z+w
|
|
1295
|
+
[3.00000000000000 + 3.00000000000000*I, 5.00000000000000 + 6.00000000000000*I]
|
|
1296
|
+
sage: z-w
|
|
1297
|
+
[-1.00000000000000 - 1.00000000000000*I, -1.00000000000000]
|
|
1298
|
+
sage: z-1
|
|
1299
|
+
[1.00000000000000*I, 1.00000000000000 + 3.00000000000000*I]
|
|
1300
|
+
sage: K=QuadraticField(5)
|
|
1301
|
+
sage: a=K.gen()
|
|
1302
|
+
sage: z-a
|
|
1303
|
+
[3.23606797749979 + 1.00000000000000*I, -0.236067977499790 + 3.00000000000000*I]
|
|
1304
|
+
sage: a-z
|
|
1305
|
+
[-3.23606797749979 - 1.00000000000000*I, 0.236067977499790 - 3.00000000000000*I]
|
|
1306
|
+
sage: w=ComplexPlaneProductElement([CC(2,2),CC(3,3),CC(4,4)]); w
|
|
1307
|
+
[2.00000000000000 + 2.00000000000000*I, 3.00000000000000 + 3.00000000000000*I, 4.00000000000000 + 4.00000000000000*I]
|
|
1308
|
+
sage: z-w
|
|
1309
|
+
Traceback (most recent call last):
|
|
1310
|
+
...
|
|
1311
|
+
TypeError: unsupported operand parent(s) for -: 'Product of complex planes of degree 2' and 'Product of complex planes of degree 3'
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
"""
|
|
1315
|
+
if self._degree != other.degree() or self._prec != other.prec():
|
|
1316
|
+
raise TypeError
|
|
1317
|
+
# Try to make an element of the same class as self and if it doesn't work, coerce to complex plane product element
|
|
1318
|
+
try:
|
|
1319
|
+
return self._parent([self._z[i] - other[i] for i in range(self.degree())])
|
|
1320
|
+
except ValueError:
|
|
1321
|
+
return ComplexPlaneProductElement__class([self._z[i] - other[i] for i in range(self.degree())])
|
|
1322
|
+
|
|
1323
|
+
cdef _mul_(self, other):
|
|
1324
|
+
r"""
|
|
1325
|
+
Multiply ``self`` by ``other`` and convert to ``parent``.
|
|
1326
|
+
|
|
1327
|
+
INPUT:
|
|
1328
|
+
- `other` - element of product of complex planes
|
|
1329
|
+
- `parent` - a parent class
|
|
1330
|
+
|
|
1331
|
+
EXAMPLES::
|
|
1332
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProductElement,ComplexPlaneProductElement__class
|
|
1333
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
1334
|
+
sage: w=ComplexPlaneProductElement([CC(2,1),CC(1,1)])
|
|
1335
|
+
sage: z*w
|
|
1336
|
+
[1.00000000000000 + 3.00000000000000*I, 3.00000000000000 + 1.00000000000000*I]
|
|
1337
|
+
sage: w*z
|
|
1338
|
+
[1.00000000000000 + 3.00000000000000*I, 3.00000000000000 + 1.00000000000000*I]
|
|
1339
|
+
sage: z*z
|
|
1340
|
+
[2.00000000000000*I, 3.00000000000000 - 4.00000000000000*I]
|
|
1341
|
+
sage: w*w
|
|
1342
|
+
[3.00000000000000 + 4.00000000000000*I, 2.00000000000000*I]
|
|
1343
|
+
sage: K=QuadraticField(5)
|
|
1344
|
+
sage: a=K.gen()
|
|
1345
|
+
sage: z*a
|
|
1346
|
+
[-2.23606797749979 - 2.23606797749979*I, 4.47213595499958 - 2.23606797749979*I]
|
|
1347
|
+
sage: a*z
|
|
1348
|
+
[-2.23606797749979 - 2.23606797749979*I, 4.47213595499958 - 2.23606797749979*I]
|
|
1349
|
+
sage: z*CC(1,3)
|
|
1350
|
+
[-2.00000000000000 + 4.00000000000000*I, 5.00000000000000 + 5.00000000000000*I]
|
|
1351
|
+
sage: z*5
|
|
1352
|
+
[5.00000000000000 + 5.00000000000000*I, 10.0000000000000 - 5.00000000000000*I]
|
|
1353
|
+
sage: u0,u1=K.unit_group().gens()
|
|
1354
|
+
sage: z*u1
|
|
1355
|
+
[1.61803398874989 + 1.61803398874989*I, -1.23606797749979 + 0.618033988749895*I]
|
|
1356
|
+
|
|
1357
|
+
# check Upper half plane elements
|
|
1358
|
+
sage: from hilbert_modgroup.all import UpperHalfPlaneProduct
|
|
1359
|
+
sage: z=UpperHalfPlaneProduct(degree=2)([1+I,1+2*I]); z
|
|
1360
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 2.00000000000000*I]
|
|
1361
|
+
sage: z*2
|
|
1362
|
+
[2.00000000000000 + 2.00000000000000*I, 2.00000000000000 + 4.00000000000000*I]
|
|
1363
|
+
sage: 2*z
|
|
1364
|
+
[2.00000000000000 + 2.00000000000000*I, 2.00000000000000 + 4.00000000000000*I]
|
|
1365
|
+
sage: type(z*2) == type(z)
|
|
1366
|
+
True
|
|
1367
|
+
sage: type(2*z) == type(z)
|
|
1368
|
+
True
|
|
1369
|
+
sage: -1*z
|
|
1370
|
+
[-1.00000000000000 - 1.00000000000000*I, -1.00000000000000 - 2.00000000000000*I]
|
|
1371
|
+
sage: w=UpperHalfPlaneProduct(degree=2)([-1+I,2+I]); w
|
|
1372
|
+
[-1.00000000000000 + 1.00000000000000*I, 2.00000000000000 + 1.00000000000000*I]
|
|
1373
|
+
sage: w*z
|
|
1374
|
+
[-2.00000000000000, 5.00000000000000*I]
|
|
1375
|
+
|
|
1376
|
+
"""
|
|
1377
|
+
if self._degree != other.degree() or self._prec != other.prec():
|
|
1378
|
+
raise TypeError
|
|
1379
|
+
try:
|
|
1380
|
+
new_element = [self._z[i]*other[i] for i in range(self.degree())]
|
|
1381
|
+
return self._parent(new_element)
|
|
1382
|
+
except ValueError:
|
|
1383
|
+
return ComplexPlaneProductElement__class(new_element)
|
|
1384
|
+
|
|
1385
|
+
cdef _div_(self, other):
|
|
1386
|
+
r"""
|
|
1387
|
+
Divide self by other.
|
|
1388
|
+
|
|
1389
|
+
INPUT:
|
|
1390
|
+
- `other` - element of product of complex planes
|
|
1391
|
+
- `parent` - parent class
|
|
1392
|
+
|
|
1393
|
+
EXAMPLES::
|
|
1394
|
+
|
|
1395
|
+
sage: from hilbert_modgroup.upper_half_plane import ComplexPlaneProductElement,ComplexPlaneProductElement__class
|
|
1396
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
1397
|
+
sage: w=ComplexPlaneProductElement([CC(2,1),CC(1,1)])
|
|
1398
|
+
sage: z / w
|
|
1399
|
+
[0.600000000000000 + 0.200000000000000*I, 0.500000000000000 - 1.50000000000000*I]
|
|
1400
|
+
sage: w / z
|
|
1401
|
+
[1.50000000000000 - 0.500000000000000*I, 0.200000000000000 + 0.600000000000000*I]
|
|
1402
|
+
sage: z / z
|
|
1403
|
+
[1.00000000000000, 1.00000000000000]
|
|
1404
|
+
sage: w / (z / z)
|
|
1405
|
+
[2.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
1406
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
1407
|
+
sage: w=ComplexPlaneProductElement([CC(2,1),CC(1,1)])
|
|
1408
|
+
sage: K=QuadraticField(5)
|
|
1409
|
+
sage: a=K.gen()
|
|
1410
|
+
sage: z/a
|
|
1411
|
+
[-0.447213595499958 - 0.447213595499958*I, 0.894427190999916 - 0.447213595499958*I]
|
|
1412
|
+
sage: a/z
|
|
1413
|
+
[-1.11803398874989 + 1.11803398874989*I, 0.894427190999916 + 0.447213595499958*I]
|
|
1414
|
+
sage: z/2
|
|
1415
|
+
[0.500000000000000 + 0.500000000000000*I, 1.00000000000000 - 0.500000000000000*I]
|
|
1416
|
+
sage: z/[0,1]
|
|
1417
|
+
Traceback (most recent call last):
|
|
1418
|
+
...
|
|
1419
|
+
ZeroDivisionError: Can not divide by zero!
|
|
1420
|
+
|
|
1421
|
+
# check Upper half plane elements
|
|
1422
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProduct
|
|
1423
|
+
sage: z=UpperHalfPlaneProduct(degree=2)([1+I,1+2*I]); z
|
|
1424
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 2.00000000000000*I]
|
|
1425
|
+
sage: z/2
|
|
1426
|
+
[0.500000000000000 + 0.500000000000000*I, 0.500000000000000 + 1.00000000000000*I]
|
|
1427
|
+
sage: type(z/2) == type(z)
|
|
1428
|
+
True
|
|
1429
|
+
sage: -1/z
|
|
1430
|
+
[-0.500000000000000 + 0.500000000000000*I, -0.200000000000000 + 0.400000000000000*I]
|
|
1431
|
+
sage: type(-1/z)==type(z)
|
|
1432
|
+
True
|
|
1433
|
+
sage: 1/z
|
|
1434
|
+
[0.500000000000000 - 0.500000000000000*I, 0.200000000000000 - 0.400000000000000*I]
|
|
1435
|
+
|
|
1436
|
+
"""
|
|
1437
|
+
if self._degree != other.degree() or self._prec != other.prec():
|
|
1438
|
+
raise TypeError
|
|
1439
|
+
if any([z == 0 for z in other]):
|
|
1440
|
+
raise ZeroDivisionError("Can not divide by zero!")
|
|
1441
|
+
new_element = [self._z[i]/other[i] for i in range(self.degree())]
|
|
1442
|
+
try:
|
|
1443
|
+
return self.parent()(new_element)
|
|
1444
|
+
except ValueError:
|
|
1445
|
+
return ComplexPlaneProductElement__class(new_element)
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
def __pow__(self, power, modulo):
|
|
1449
|
+
"""
|
|
1450
|
+
Self to the power 'power' defined component-wise:
|
|
1451
|
+
If `power` is a scalar:
|
|
1452
|
+
z^power = (z_1^power,...,z_n^power)
|
|
1453
|
+
If `power` is an element of this class:
|
|
1454
|
+
z^power = (z_1^power_1,...,z_n^power_n)
|
|
1455
|
+
|
|
1456
|
+
INPUT:
|
|
1457
|
+
|
|
1458
|
+
- `power` -- complex number (will be coerced to the base_ring of self)
|
|
1459
|
+
- `modulo` -- dummy argument (ignored)
|
|
1460
|
+
|
|
1461
|
+
EXAMPLES::
|
|
1462
|
+
|
|
1463
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1464
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)])
|
|
1465
|
+
sage: z**2
|
|
1466
|
+
[2.00000000000000*I, 3.00000000000000 - 4.00000000000000*I]
|
|
1467
|
+
sage: z**[2,2]
|
|
1468
|
+
[2.00000000000000*I, 3.00000000000000 - 4.00000000000000*I]
|
|
1469
|
+
sage: z**[1,2]
|
|
1470
|
+
[1.00000000000000 + 1.00000000000000*I, 3.00000000000000 - 4.00000000000000*I]
|
|
1471
|
+
sage: w=ComplexPlaneProductElement([CC(2,1),CC(1,1)])
|
|
1472
|
+
sage: z**w
|
|
1473
|
+
[-0.309743504928494 + 0.857658012588736*I, 3.35025931507288 + 1.18915022150040*I]
|
|
1474
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(0,0)]);
|
|
1475
|
+
sage: z**2
|
|
1476
|
+
[2.00000000000000*I, 0]
|
|
1477
|
+
sage: z**-2
|
|
1478
|
+
Traceback (most recent call last):
|
|
1479
|
+
...
|
|
1480
|
+
ZeroDivisionError: Can not divide component by 0!
|
|
1481
|
+
sage: z**[-2,1]
|
|
1482
|
+
[ - 0.500000000000000*I, 0]
|
|
1483
|
+
sage: z**[-2,0]
|
|
1484
|
+
[ - 0.500000000000000*I, 1.00000000000000]
|
|
1485
|
+
"""
|
|
1486
|
+
|
|
1487
|
+
if modulo:
|
|
1488
|
+
raise RuntimeError("__pow__ dummy argument ignored")
|
|
1489
|
+
try:
|
|
1490
|
+
if not isinstance(power,(list,ComplexPlaneProductElement__class)):
|
|
1491
|
+
power = [power]*self.degree()
|
|
1492
|
+
power = self.parent()(power)
|
|
1493
|
+
if any(power[i].real() < 0 and self[i] == 0 for i in range(self.degree())):
|
|
1494
|
+
raise ZeroDivisionError("Can not divide component by 0!")
|
|
1495
|
+
new_element = [z**power[i] for i,z in enumerate(self)]
|
|
1496
|
+
try:
|
|
1497
|
+
return self.parent()(new_element)
|
|
1498
|
+
except ValueError:
|
|
1499
|
+
return ComplexPlaneProductElement__class(new_element)
|
|
1500
|
+
except TypeError as e:
|
|
1501
|
+
raise TypeError(f"Can not coerce {power} to self.base_ring(). {e}")
|
|
1502
|
+
|
|
1503
|
+
|
|
1504
|
+
cpdef trace(self):
|
|
1505
|
+
"""
|
|
1506
|
+
Trace of self, i.e. sum over all components.
|
|
1507
|
+
|
|
1508
|
+
|
|
1509
|
+
EXAMPLES::
|
|
1510
|
+
|
|
1511
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1512
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]);z
|
|
1513
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1514
|
+
sage: z.trace()
|
|
1515
|
+
3.00000000000000
|
|
1516
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1),CC(4,2)])
|
|
1517
|
+
sage: z.trace()
|
|
1518
|
+
7.00000000000000 + 2.00000000000000*I
|
|
1519
|
+
|
|
1520
|
+
"""
|
|
1521
|
+
return sum(self)
|
|
1522
|
+
|
|
1523
|
+
cpdef real_trace(self):
|
|
1524
|
+
"""
|
|
1525
|
+
Trace of real part self, i.e. sum over all components.
|
|
1526
|
+
|
|
1527
|
+
EXAMPLES::
|
|
1528
|
+
|
|
1529
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1530
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]);z
|
|
1531
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1532
|
+
sage: z.real_trace()
|
|
1533
|
+
3.00000000000000
|
|
1534
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1),CC(4,2)])
|
|
1535
|
+
sage: z.real_trace()
|
|
1536
|
+
7.00000000000000
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
"""
|
|
1540
|
+
return sum(self.real())
|
|
1541
|
+
|
|
1542
|
+
cpdef imag_trace(self):
|
|
1543
|
+
"""
|
|
1544
|
+
Trace of imaginary part of self, i.e. sum over all components.
|
|
1545
|
+
|
|
1546
|
+
EXAMPLES::
|
|
1547
|
+
|
|
1548
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement
|
|
1549
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1)]);z
|
|
1550
|
+
[1.00000000000000 + 1.00000000000000*I, 2.00000000000000 - 1.00000000000000*I]
|
|
1551
|
+
sage: z.imag_trace()
|
|
1552
|
+
0.000000000000000
|
|
1553
|
+
sage: z=ComplexPlaneProductElement([CC(1,1),CC(2,-1),CC(4,2)])
|
|
1554
|
+
sage: z.imag_trace()
|
|
1555
|
+
2.00000000000000
|
|
1556
|
+
|
|
1557
|
+
"""
|
|
1558
|
+
return sum(self.imag())
|
|
1559
|
+
|
|
1560
|
+
cpdef apply(self, m):
|
|
1561
|
+
r"""
|
|
1562
|
+
Apply the matrix m to self.
|
|
1563
|
+
|
|
1564
|
+
INPUT:
|
|
1565
|
+
|
|
1566
|
+
- ``m`` -- matrix
|
|
1567
|
+
|
|
1568
|
+
EXAMPLES::
|
|
1569
|
+
|
|
1570
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement, UpperHalfPlaneProductElement, HilbertModularGroup
|
|
1571
|
+
sage: z=ComplexPlaneProductElement([CC(3,1),CC(1,-1)]);z
|
|
1572
|
+
[3.00000000000000 + 1.00000000000000*I, 1.00000000000000 - 1.00000000000000*I]
|
|
1573
|
+
sage: z=ComplexPlaneProductElement([CC(3,1),CC(-1,1)]);z
|
|
1574
|
+
[3.00000000000000 + 1.00000000000000*I, -1.00000000000000 + 1.00000000000000*I]
|
|
1575
|
+
sage: N = matrix(ZZ,[[1,0],[0,1]])
|
|
1576
|
+
sage: z.apply(N)
|
|
1577
|
+
[3.00000000000000 + 1.00000000000000*I, -1.00000000000000 + 1.00000000000000*I]
|
|
1578
|
+
sage: A=matrix(ZZ,[[0,-1],[1,0]])
|
|
1579
|
+
sage: z.apply(A)
|
|
1580
|
+
[-0.300000000000000 + 0.100000000000000*I, 0.500000000000000 + 0.500000000000000*I]
|
|
1581
|
+
sage: H5 = HilbertModularGroup(5)
|
|
1582
|
+
sage: A = H5(A)
|
|
1583
|
+
sage: z=UpperHalfPlaneProductElement([CC(3,1),CC(-1,1)])
|
|
1584
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProductElement__class
|
|
1585
|
+
sage: z.apply(A)
|
|
1586
|
+
[-0.300000000000000 + 0.100000000000000*I, 0.500000000000000 + 0.500000000000000*I]
|
|
1587
|
+
sage: isinstance(_, UpperHalfPlaneProductElement__class)
|
|
1588
|
+
True
|
|
1589
|
+
sage: CF = ComplexField(103)
|
|
1590
|
+
sage: z = UpperHalfPlaneProductElement([CF(0.5, 0.5),CF(1,1)])
|
|
1591
|
+
sage: z.apply(A)
|
|
1592
|
+
[-1.00000000000000000000000000000 + 1.00000000000000000000000000000*I, ...
|
|
1593
|
+
sage: a=H5.base_ring().number_field().gen()
|
|
1594
|
+
sage: A = H5.cusp_normalizing_map(NFCusp(H5.base_ring().number_field(),a,1+a))
|
|
1595
|
+
sage: z.apply(A)
|
|
1596
|
+
[1.53825552559559453517100534830 + 0.0586313287080522798416723065016*I, ...
|
|
1597
|
+
|
|
1598
|
+
"""
|
|
1599
|
+
try:
|
|
1600
|
+
aa, bb, cc, dd = m.list()
|
|
1601
|
+
except (AttributeError,ValueError):
|
|
1602
|
+
raise ValueError("Need a 2 x 2 matrix or object that contains a list of 4 elements to act on self.")
|
|
1603
|
+
|
|
1604
|
+
try:
|
|
1605
|
+
aa, bb, cc, dd = m.list()
|
|
1606
|
+
except (AttributeError, ValueError):
|
|
1607
|
+
raise ValueError(
|
|
1608
|
+
"Need a 2 x 2 matrix or object that contains a list of 4 elements to act on self.")
|
|
1609
|
+
prec = self.prec()
|
|
1610
|
+
if hasattr(aa,'complex_embeddings'):
|
|
1611
|
+
a = aa.complex_embeddings(prec)
|
|
1612
|
+
b = bb.complex_embeddings(prec)
|
|
1613
|
+
c = cc.complex_embeddings(prec)
|
|
1614
|
+
d = dd.complex_embeddings(prec)
|
|
1615
|
+
else:
|
|
1616
|
+
a = [RealField(prec)(aa)]*self._degree
|
|
1617
|
+
b = [RealField(prec)(bb)]*self._degree
|
|
1618
|
+
c = [RealField(prec)(cc)]*self._degree
|
|
1619
|
+
d = [RealField(prec)(dd)]*self._degree
|
|
1620
|
+
## Component - wise application of map
|
|
1621
|
+
denominators = [(c[i]*z+d[i]) for i, z in enumerate(self._z)]
|
|
1622
|
+
if 0 in denominators:
|
|
1623
|
+
return Infinity
|
|
1624
|
+
zlist = [ (a[i]*z+b[i])/denominators[i] for i, z in enumerate(self._z)]
|
|
1625
|
+
return self.parent()(zlist)
|
|
1626
|
+
|
|
1627
|
+
def as_ComplexPlaneProductElement(self):
|
|
1628
|
+
"""
|
|
1629
|
+
Convert self to an element in the product of complex planes.
|
|
1630
|
+
|
|
1631
|
+
EXAMPLES::
|
|
1632
|
+
|
|
1633
|
+
sage: from hilbert_modgroup.all import UpperHalfPlaneProductElement
|
|
1634
|
+
sage: z = UpperHalfPlaneProductElement([1+I,1+I])
|
|
1635
|
+
sage: z.as_ComplexPlaneProductElement()
|
|
1636
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
1637
|
+
|
|
1638
|
+
sage: z = UpperHalfPlaneProductElement([1+I,1+I,1+I,1+I])
|
|
1639
|
+
sage: z.as_ComplexPlaneProductElement()
|
|
1640
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
1641
|
+
|
|
1642
|
+
"""
|
|
1643
|
+
if self.__class__ == ComplexPlaneProductElement__class:
|
|
1644
|
+
return self
|
|
1645
|
+
return ComplexPlaneProductElement(list(self), prec=self.parent().prec())
|
|
1646
|
+
|
|
1647
|
+
def permute(self,s):
|
|
1648
|
+
r"""
|
|
1649
|
+
The permutation group acts by permuting the components.
|
|
1650
|
+
|
|
1651
|
+
EXAMPLES::
|
|
1652
|
+
|
|
1653
|
+
sage: from hilbert_modgroup.all import UpperHalfPlaneProductElement
|
|
1654
|
+
sage: from sage.groups.perm_gps.constructor import PermutationGroupElement
|
|
1655
|
+
sage: g=PermutationGroupElement([2,1])
|
|
1656
|
+
sage: z = UpperHalfPlaneProductElement([1+I,2+2*I])
|
|
1657
|
+
sage: z.permute(g)
|
|
1658
|
+
[2.00000000000000 + 2.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
1659
|
+
sage: z = UpperHalfPlaneProductElement([1+I,2+I,3+I,4+I])
|
|
1660
|
+
sage: g=PermutationGroupElement([2,1])
|
|
1661
|
+
sage: z.permute(g)
|
|
1662
|
+
[2.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I, 3.00000000000000 + 1.00000000000000*I, 4.00000000000000 + 1.00000000000000*I]
|
|
1663
|
+
sage: g=PermutationGroupElement([2,1,4,3])
|
|
1664
|
+
sage: z.permute(g)
|
|
1665
|
+
[2.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I, 4.00000000000000 + 1.00000000000000*I, 3.00000000000000 + 1.00000000000000*I]
|
|
1666
|
+
|
|
1667
|
+
|
|
1668
|
+
"""
|
|
1669
|
+
if not isinstance(s, PermutationGroupElement):
|
|
1670
|
+
raise ValueError("Input must be a permutation group element")
|
|
1671
|
+
znew = [0 for i in range(self._degree)]
|
|
1672
|
+
for i in range(self._degree):
|
|
1673
|
+
si = s(i+1)-1
|
|
1674
|
+
znew[si]=self.z()[i]
|
|
1675
|
+
return self.parent()(znew)
|
|
1676
|
+
|
|
1677
|
+
cpdef reflect(self):
|
|
1678
|
+
r"""
|
|
1679
|
+
Reflection of self in each coordinate in the imaginary axis.
|
|
1680
|
+
|
|
1681
|
+
EXAMPLES::
|
|
1682
|
+
|
|
1683
|
+
sage: from hilbert_modgroup.all import UpperHalfPlaneProductElement
|
|
1684
|
+
sage: z = UpperHalfPlaneProductElement([1+I,2+2*I])
|
|
1685
|
+
sage: z.reflect()
|
|
1686
|
+
[-1.00000000000000 + 1.00000000000000*I, -2.00000000000000 + 2.00000000000000*I]
|
|
1687
|
+
|
|
1688
|
+
sage: z = UpperHalfPlaneProductElement([1+I,1+I,1+I,1+I])
|
|
1689
|
+
sage: z.reflect()
|
|
1690
|
+
[-1.00000000000000 + 1.00000000000000*I, -1.00000000000000 + 1.00000000000000*I, -1.00000000000000 + 1.00000000000000*I, -1.00000000000000 + 1.00000000000000*I]
|
|
1691
|
+
|
|
1692
|
+
"""
|
|
1693
|
+
znew = [0 for i in range(self._degree)]
|
|
1694
|
+
for i in range(self.degree()):
|
|
1695
|
+
znew[i] = MPComplexField(self._prec)(-self._x[i],self._y[i])
|
|
1696
|
+
return self.parent()(znew)
|
|
1697
|
+
|
|
1698
|
+
|
|
1699
|
+
|
|
1700
|
+
cdef class UpperHalfPlaneProductElement__class(ComplexPlaneProductElement__class):
|
|
1701
|
+
r"""
|
|
1702
|
+
Class for elements of products of the upper half plane.
|
|
1703
|
+
|
|
1704
|
+
"""
|
|
1705
|
+
|
|
1706
|
+
def __init__(self, zl, verbose=0, *argv, **kwds):
|
|
1707
|
+
r"""
|
|
1708
|
+
Init self from list of complex numbers.
|
|
1709
|
+
|
|
1710
|
+
EXAMPLES::
|
|
1711
|
+
|
|
1712
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProductElement__class
|
|
1713
|
+
sage: from sage.rings.complex_mpc import MPComplexField
|
|
1714
|
+
sage: MPC = MPComplexField(53)
|
|
1715
|
+
sage: z = UpperHalfPlaneProductElement__class([MPC(1,1),MPC(1,1)])
|
|
1716
|
+
sage: TestSuite(z).run()
|
|
1717
|
+
sage: z
|
|
1718
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
1719
|
+
sage: UpperHalfPlaneProductElement__class([MPC(1,1),MPC(1,1),MPC(1,1)])
|
|
1720
|
+
[1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I, 1.00000000000000 + 1.00000000000000*I]
|
|
1721
|
+
|
|
1722
|
+
TESTS:
|
|
1723
|
+
sage: UpperHalfPlaneProductElement__class([1+I,1+I])
|
|
1724
|
+
Traceback (most recent call last):
|
|
1725
|
+
...
|
|
1726
|
+
ValueError: Need a list of MPComplexNumber
|
|
1727
|
+
|
|
1728
|
+
"""
|
|
1729
|
+
super().__init__(zl,verbose=verbose,*argv,**kwds)
|
|
1730
|
+
if not self.is_in_upper_half_plane():
|
|
1731
|
+
raise ValueError("Point {0} not in upper half-plane!".format(zl))
|
|
1732
|
+
|
|
1733
|
+
def __reduce__(self):
|
|
1734
|
+
r"""
|
|
1735
|
+
Prepare self for pickling
|
|
1736
|
+
|
|
1737
|
+
TESTS::
|
|
1738
|
+
|
|
1739
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProductElement
|
|
1740
|
+
sage: c = UpperHalfPlaneProductElement([1,1])
|
|
1741
|
+
sage: loads(dumps(c)) == c
|
|
1742
|
+
True
|
|
1743
|
+
|
|
1744
|
+
"""
|
|
1745
|
+
return UpperHalfPlaneProductElement, (self.z(),)
|
|
1746
|
+
|
|
1747
|
+
def imag_log(self):
|
|
1748
|
+
r"""
|
|
1749
|
+
The logarithmic embedding of the products of upper half-planes into R^k given by log.
|
|
1750
|
+
|
|
1751
|
+
EXAMPLES:
|
|
1752
|
+
|
|
1753
|
+
sage: from hilbert_modgroup.all import UpperHalfPlaneProductElement
|
|
1754
|
+
sage: z=UpperHalfPlaneProductElement([CC(1,3),CC(1,2)])
|
|
1755
|
+
sage: z.imag_log()
|
|
1756
|
+
(1.09861228866811, 0.693147180559945)
|
|
1757
|
+
|
|
1758
|
+
"""
|
|
1759
|
+
return vector([x.imag().log() for x in self])
|
|
1760
|
+
|
|
1761
|
+
def hyp_dist(self, w, dtype=1):
|
|
1762
|
+
r"""
|
|
1763
|
+
Return "a" hyperbolic distance between ``self`` and ``w``
|
|
1764
|
+
|
|
1765
|
+
INPUT:
|
|
1766
|
+
- `w` -- element of the upper half plane
|
|
1767
|
+
- `dtype` -- integer (default=1).
|
|
1768
|
+
If dtype == 0 the combined distance is the sum of all components
|
|
1769
|
+
If dtype == 1 the combined distance is the maximum of all components.
|
|
1770
|
+
|
|
1771
|
+
EXAMPLES::
|
|
1772
|
+
|
|
1773
|
+
sage: from hilbert_modgroup.all import UpperHalfPlaneProductElement
|
|
1774
|
+
sage: z = UpperHalfPlaneProductElement([1+I,2+2*I])
|
|
1775
|
+
sage: w = UpperHalfPlaneProductElement([2+I,2+2*I])
|
|
1776
|
+
sage: z.hyp_dist(z)
|
|
1777
|
+
0
|
|
1778
|
+
sage: z.hyp_dist(w)
|
|
1779
|
+
0.962423650119207
|
|
1780
|
+
|
|
1781
|
+
"""
|
|
1782
|
+
if dtype == 1:
|
|
1783
|
+
maxd = 0
|
|
1784
|
+
if not isinstance(w,UpperHalfPlaneProductElement__class) or w.degree() != self.degree():
|
|
1785
|
+
raise ValueError("w must be an element of the same degree")
|
|
1786
|
+
|
|
1787
|
+
if w.z() == self.z():
|
|
1788
|
+
return 0
|
|
1789
|
+
distances = []
|
|
1790
|
+
for i in range(self.degree()):
|
|
1791
|
+
ab1 = abs(self.z()[i] - w.z()[i])
|
|
1792
|
+
ab2 = abs(self.z()[i] - MPComplexField(self._prec)(w.real()[i], -w.imag()[i]))
|
|
1793
|
+
l = ((ab1 + ab2) / (ab2 - ab1)).log()
|
|
1794
|
+
distances.append(l)
|
|
1795
|
+
|
|
1796
|
+
if dtype == 0:
|
|
1797
|
+
return sum(distances)
|
|
1798
|
+
else:
|
|
1799
|
+
return max(distances)
|
|
1800
|
+
|
|
1801
|
+
cpdef apply(self, m):
|
|
1802
|
+
r"""
|
|
1803
|
+
Apply the matrix m to self.
|
|
1804
|
+
|
|
1805
|
+
INPUT:
|
|
1806
|
+
|
|
1807
|
+
- ``m`` -- matrix
|
|
1808
|
+
|
|
1809
|
+
EXAMPLES::
|
|
1810
|
+
|
|
1811
|
+
sage: from hilbert_modgroup.all import ComplexPlaneProductElement, UpperHalfPlaneProductElement, HilbertModularGroup
|
|
1812
|
+
sage: H5 = HilbertModularGroup(5)
|
|
1813
|
+
sage: A=matrix(ZZ,[[0,-1],[1,0]])
|
|
1814
|
+
sage: A = H5(A)
|
|
1815
|
+
sage: z=UpperHalfPlaneProductElement([CC(3,1),CC(-1,1)])
|
|
1816
|
+
sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProductElement__class
|
|
1817
|
+
sage: z.apply(A)
|
|
1818
|
+
[-0.300000000000000 + 0.100000000000000*I, 0.500000000000000 + 0.500000000000000*I]
|
|
1819
|
+
sage: isinstance(_, UpperHalfPlaneProductElement__class)
|
|
1820
|
+
True
|
|
1821
|
+
sage: a=H5.base_ring().number_field().gen()
|
|
1822
|
+
sage: A = H5.cusp_normalizing_map(NFCusp(H5.base_ring().number_field(),a,1+a))
|
|
1823
|
+
sage: z.apply(A)
|
|
1824
|
+
[1.67855780465319 + 0.0271280367431345*I, 0.717919314224174 + 0.0871677256896697*I]
|
|
1825
|
+
|
|
1826
|
+
"""
|
|
1827
|
+
new_point = super(UpperHalfPlaneProductElement__class,self).apply(m)
|
|
1828
|
+
return new_point.as_upper_half_plane_element()
|