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.

@@ -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()