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,623 @@
1
+ """
2
+ Element of Hilbert modular groups
3
+
4
+
5
+ AUTHORS:
6
+
7
+ - Fredrik Stromberg (2021)
8
+
9
+ NOTE: The structure of this class is based on ArithmeticSubgroupElement from sage/modular/arithgroup/arithgroup_element.pyx
10
+ """
11
+ from sage.structure.element cimport MultiplicativeGroupElement, InfinityElement
12
+ from sage.structure.richcmp cimport richcmp
13
+ from sage.rings.integer_ring import Z as ZZ
14
+ from sage.rings.infinity import infinity
15
+ from sage.matrix.matrix_space import MatrixSpace
16
+ from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense
17
+ from sage.misc.cachefunc import cached_method
18
+ from sage.rings.infinity import infinity
19
+
20
+ from hilbert_modgroup.upper_half_plane cimport ComplexPlaneProductElement__class, UpperHalfPlaneProductElement__class
21
+
22
+ cdef class HilbertModularGroupElement(MultiplicativeGroupElement):
23
+
24
+
25
+ cdef Matrix_generic_dense __x
26
+
27
+ def __init__(self, parent, x, check=True):
28
+ """
29
+ Create an element of a hilbert Modular Group.
30
+
31
+ INPUT:
32
+
33
+ - ``parent`` -- an arithmetic subgroup
34
+
35
+ - `x` -- data defining a 2x2 matrix over ZZ
36
+ which lives in parent
37
+
38
+
39
+ EXAMPLES::
40
+
41
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
42
+ sage: from hilbert_modgroup.hilbert_modular_group_element import HilbertModularGroupElement
43
+ sage: H=HilbertModularGroup(5)
44
+ sage: TestSuite(H).run()
45
+ sage: x,y=H.base_ring().gens()
46
+ sage: HilbertModularGroupElement(H,[1,x,0,1])
47
+ [ 1 1/2*a + 1/2]
48
+ [ 0 1]
49
+ sage: HilbertModularGroupElement(H,[1,y,0,1])
50
+ [1 a]
51
+ [0 1]
52
+ sage: HilbertModularGroupElement(H,[1,y,0,1]) in H
53
+ True
54
+
55
+ """
56
+ if not 'HilbertModularGroup_class' in parent.__class__.__name__:
57
+ raise TypeError("parent (= {0}) must be a Hilbert Modular group".format(parent))
58
+ x = MatrixSpace(parent.base_ring(),2,2)(x, copy=True, coerce=True)
59
+ if x.determinant() != 1:
60
+ raise TypeError("matrix must have determinant 1")
61
+ x.set_immutable()
62
+ MultiplicativeGroupElement.__init__(self, parent)
63
+ self.__x = x
64
+
65
+ def __iter__(self):
66
+ """
67
+ Iterate over self.
68
+
69
+ EXAMPLES::
70
+
71
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
72
+ sage: H=HilbertModularGroup(5)
73
+ sage: x,y=H.base_ring().gens()
74
+ sage: A = H([1,x,0,1])
75
+ sage: list(A)
76
+ [1, 1/2*a + 1/2, 0, 1]
77
+
78
+ """
79
+ yield self.__x[0, 0]
80
+ yield self.__x[0, 1]
81
+ yield self.__x[1, 0]
82
+ yield self.__x[1, 1]
83
+
84
+ def list(self):
85
+ r"""
86
+ List of ``self``.
87
+
88
+ EXAMPLES::
89
+
90
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
91
+ sage: H=HilbertModularGroup(5)
92
+ sage: x,y=H.base_ring().gens()
93
+ sage: A = H([1,x,0,1])
94
+ sage: A.list()
95
+ [1, 1/2*a + 1/2, 0, 1]
96
+ """
97
+ return list(self)
98
+
99
+ def __repr__(self):
100
+ r"""
101
+ Return the string representation of ``self``.
102
+
103
+ EXAMPLES::
104
+
105
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
106
+ sage: H=HilbertModularGroup(5); H
107
+ Hilbert Modular Group ... x^2 - 5 with a = 2.236067977499790?
108
+
109
+ """
110
+ return repr(self.__x)
111
+
112
+ def _latex_(self):
113
+ r"""
114
+ Return the latex representation of ``self``.
115
+
116
+ EXAMPLES::
117
+
118
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
119
+ sage: H=HilbertModularGroup(5)
120
+ sage: x,y=H.base_ring().gens()
121
+ sage: A = H([1,x,0,1])
122
+ sage: latex(A)
123
+ \left(\begin{array}{rr}
124
+ 1 & \frac{1}{2} \sqrt{5} + \frac{1}{2} \\
125
+ 0 & 1
126
+ \end{array}\right)
127
+
128
+ """
129
+ return self.__x._latex_()
130
+
131
+ cpdef _richcmp_(self, right_r, int op):
132
+ r"""
133
+ Compare self to right, where right is guaranteed to have the same
134
+ parent as self.
135
+
136
+ EXAMPLES::
137
+
138
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
139
+ sage: H=HilbertModularGroup(5)
140
+ sage: x,y=H.base_ring().gens()
141
+ sage: A = H([1,x,0,1])
142
+ sage: B = H([1,y,0,1])
143
+ sage: A == B
144
+ False
145
+ sage: A != B
146
+ True
147
+ sage: A < B
148
+ True
149
+ sage: A > B
150
+ False
151
+
152
+ """
153
+ cdef HilbertModularGroupElement right = <HilbertModularGroupElement>right_r
154
+ return richcmp(self.__x, right.__x, op)
155
+
156
+ def __nonzero__(self):
157
+ """
158
+ Return ``True``, since the ``self`` lives in SL(2,\Z), which does not
159
+ contain the zero matrix.
160
+
161
+ EXAMPLES::
162
+
163
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
164
+ sage: H=HilbertModularGroup(5)
165
+ sage: x,y=H.base_ring().gens()
166
+ sage: A = H([1,x,0,1])
167
+ sage: bool(A)
168
+ True
169
+ """
170
+ return True
171
+
172
+ cpdef _mul_(self, right):
173
+ """
174
+ Return self * right.
175
+
176
+ EXAMPLES::
177
+
178
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
179
+ sage: H=HilbertModularGroup(5)
180
+ sage: x,y=H.base_ring().gens()
181
+ sage: A = H([1,x,0,1])
182
+ sage: B = H([1,y,0,1])
183
+ sage: C = A*B
184
+ sage: C
185
+ [ 1 3/2*a + 1/2]
186
+ [ 0 1]
187
+ sage: C.parent()
188
+ Hilbert Modular Group ... x^2 - 5 with a = 2.236067977499790?
189
+
190
+ """
191
+ return self.__class__(self.parent(), self.__x * (<HilbertModularGroupElement> right).__x, check=False)
192
+
193
+ def __invert__(self):
194
+ r"""
195
+ Return the inverse of ``self``.
196
+
197
+ EXAMPLES::
198
+
199
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
200
+ sage: H=HilbertModularGroup(5)
201
+ sage: x,y=H.base_ring().gens()
202
+ sage: H([1,x,0,1]).__invert__()
203
+ [ 1 -1/2*a - 1/2]
204
+ [ 0 1]
205
+ """
206
+ return self._parent(
207
+ [self.__x.get_unsafe(1, 1), -self.__x.get_unsafe(0, 1),
208
+ -self.__x.get_unsafe(1, 0), self.__x.get_unsafe(0, 0)]
209
+ )
210
+
211
+ def matrix(self):
212
+ """
213
+ Return the matrix corresponding to ``self``.
214
+
215
+ EXAMPLES::
216
+
217
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
218
+ sage: H=HilbertModularGroup(5)
219
+ sage: x,y=H.base_ring().gens()
220
+ sage: A = H([1,x,0,1]); A
221
+ [ 1 1/2*a + 1/2]
222
+ [ 0 1]
223
+ sage: A.matrix()
224
+ [ 1 1/2*a + 1/2]
225
+ [ 0 1]
226
+ sage: type(A.matrix())
227
+ <class 'sage.matrix.matrix_generic_dense.Matrix_generic_dense'>
228
+ """
229
+ return self.__x
230
+
231
+ def determinant(self):
232
+ """
233
+ Return the determinant of ``self``, which is always 1.
234
+
235
+ EXAMPLES::
236
+
237
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
238
+ sage: H=HilbertModularGroup(5)
239
+ sage: x,y=H.base_ring().gens()
240
+ sage: A = H([1,x,0,1])
241
+ sage: A.determinant()
242
+ 1
243
+ """
244
+ return self.base_ring().one()
245
+
246
+ def det(self):
247
+ """
248
+ Return the determinant of ``self``, which is always 1.
249
+
250
+ EXAMPLES::
251
+
252
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
253
+ sage: H=HilbertModularGroup(5)
254
+ sage: x,y=H.base_ring().gens()
255
+ sage: A =H([1,x,0,1])
256
+ sage: A.determinant()
257
+ 1
258
+ """
259
+ return self.determinant()
260
+
261
+ def a(self):
262
+ """
263
+ Return the upper left entry of ``self``.
264
+
265
+ EXAMPLES::
266
+
267
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
268
+ sage: H=HilbertModularGroup(5)
269
+ sage: x,y=H.base_ring().gens()
270
+ sage: A = H([1,x,0,1]); A
271
+ [ 1 1/2*a + 1/2]
272
+ [ 0 1]
273
+ sage: A.a()
274
+ 1
275
+ """
276
+ return self.__x.get_unsafe(0, 0)
277
+
278
+ def b(self):
279
+ """
280
+ Return the upper right entry of ``self``.
281
+
282
+ EXAMPLES::
283
+
284
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
285
+ sage: H=HilbertModularGroup(5)
286
+ sage: x,y=H.base_ring().gens()
287
+ sage: A = H([1,x,0,1]); A
288
+ [ 1 1/2*a + 1/2]
289
+ [ 0 1]
290
+ sage: A.b()
291
+ 1/2*a + 1/2
292
+ """
293
+ return self.__x.get_unsafe(0, 1)
294
+
295
+ def c(self):
296
+ """
297
+ Return the lower left entry of ``self``.
298
+
299
+ EXAMPLES::
300
+
301
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
302
+ sage: H=HilbertModularGroup(5)
303
+ sage: x,y=H.base_ring().gens()
304
+ sage: A = H([1,x,0,1]); A
305
+ [ 1 1/2*a + 1/2]
306
+ [ 0 1]
307
+ sage: A.c()
308
+ 0
309
+
310
+ """
311
+ return self.__x.get_unsafe(1, 0)
312
+
313
+ def d(self):
314
+ """
315
+ Return the lower right entry of ``self``.
316
+
317
+ EXAMPLES::
318
+
319
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
320
+ sage: H=HilbertModularGroup(5)
321
+ sage: x,y=H.base_ring().gens()
322
+ sage: A = H([1,x,0,1]); A
323
+ [ 1 1/2*a + 1/2]
324
+ [ 0 1]
325
+ sage: A.d()
326
+ 1
327
+
328
+ """
329
+ return self.__x.get_unsafe(1, 1)
330
+
331
+ def acton(self, z):
332
+ """
333
+ Return the result of the action of ``self`` on z as a fractional linear
334
+ transformation.
335
+
336
+ EXAMPLES::
337
+
338
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
339
+ sage: H=HilbertModularGroup(5)
340
+ sage: x,y=H.base_ring().gens()
341
+ sage: A = H([1,x,x,x+2]); A
342
+ [ 1 1/2*a + 1/2]
343
+ [1/2*a + 1/2 1/2*a + 5/2]
344
+
345
+
346
+ An example of A acting on a symbolic variable::
347
+
348
+ sage: from sage.rings.integer_ring import Z as ZZ
349
+ sage: z = ZZ['z'].gen()
350
+ sage: A.acton(z)
351
+ (z + 1/2*a + 1/2)/((1/2*a + 1/2)*z + 1/2*a + 5/2)
352
+
353
+ An example of A acting on an element of the base field:
354
+
355
+ sage: K = A.base_ring().number_field(); K
356
+ Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?
357
+ sage: a = K.gen()
358
+ sage: z = a/7 +1/12; z
359
+ 1/7*a + 1/12
360
+ sage: z in A.base_ring().number_field()
361
+ True
362
+ sage: A.acton(z)
363
+ 21251/92062*a - 3947/92062
364
+
365
+ An example with complex numbers::
366
+
367
+ sage: C.<i> = ComplexField()
368
+ sage: A.acton(i)
369
+ 0.475683661041614 + 0.0636610018750175*I
370
+
371
+ An example with the cusp infinity::
372
+
373
+ sage: A.acton(infinity)
374
+ 1/2*a - 1/2
375
+
376
+ An example which maps a finite cusp to infinity::
377
+
378
+ sage: A.acton(-a)
379
+ +Infinity
380
+
381
+ An example acting on the NFCusp elements
382
+
383
+ sage: c=NFCusp(K,-a,1)
384
+ sage: c
385
+ Cusp [-a: 1] of Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?
386
+ sage: A.acton(c)
387
+ +Infinity
388
+
389
+ another example of acting on a NFCusp element
390
+
391
+ sage: c=NFCusp(K,a/7 +1/12); c
392
+ Cusp [12*a + 7: 84] of Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?
393
+ sage: A.acton(c)
394
+ 21251/92062*a - 3947/92062
395
+
396
+ Example acting on points in the upper half-plane
397
+
398
+ sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProductElement
399
+ sage: z=UpperHalfPlaneProductElement([CC(0,1),CC(0,1)]); z
400
+ [1.00000000000000*I, 1.00000000000000*I]
401
+ sage: A.acton(z)
402
+ [-0.642350327708281 + 0.436338998124982*I, 0.475683661041614 + 0.0636610018750175*I]
403
+ sage: S=H([0,-1,1,0])
404
+ sage: S.acton(z)
405
+ [1.00000000000000*I, 1.00000000000000*I]
406
+
407
+ NOTE: when acting on instances of cusps the return value
408
+ is still an element of the underlying number field or infinity (Note the presence of
409
+ '+', which does not show up for cusp instances)::
410
+
411
+
412
+ TESTS:
413
+
414
+ We cover the remaining case, i.e., infinity mapped to infinity::
415
+
416
+ sage: H([1, K.gen(), 0, 1]).acton(infinity)
417
+ +Infinity
418
+ """
419
+ if isinstance(z, InfinityElement):
420
+ if self.c() != 0:
421
+ return self.a() / self.c()
422
+ else:
423
+ return infinity
424
+ if hasattr(z, 'denominator') and hasattr(z, 'numerator'):
425
+ p = z.numerator()
426
+ q = z.denominator()
427
+ P = self.a() * p + self.b() * q
428
+ Q = self.c() * p + self.d() * q
429
+ if not Q and P:
430
+ return infinity
431
+ else:
432
+ return P / Q
433
+ if isinstance(z, ComplexPlaneProductElement__class):
434
+ return self._acton_complex_plane_element(z)
435
+ try:
436
+ return (self.a() * z + self.b()) / (self.c() * z + self.d())
437
+ except:
438
+ raise ValueError(f"Can not apply self to z of type: {type(z)}")
439
+
440
+ cpdef _acton_complex_plane_element(self, ComplexPlaneProductElement__class z):
441
+ """
442
+ Act on an element of the type ComplexPlaneProductElement__class
443
+
444
+ EXAMPLES::
445
+
446
+ sage: from hilbert_modgroup.upper_half_plane import UpperHalfPlaneProductElement
447
+ sage: from hilbert_modgroup.all import HilbertModularGroup
448
+ sage: H=HilbertModularGroup(5)
449
+ sage: x,y=H.base_ring().gens()
450
+ sage: A = H([1,x,x,x+2]); A
451
+ [ 1 1/2*a + 1/2]
452
+ [1/2*a + 1/2 1/2*a + 5/2]
453
+ sage: z=UpperHalfPlaneProductElement([CC(0,1),CC(0,1)]); z
454
+ [1.00000000000000*I, 1.00000000000000*I]
455
+ sage: A._acton_complex_plane_element(z)
456
+ [-0.642350327708281 + 0.436338998124982*I, 0.475683661041614 + 0.0636610018750175*I]
457
+ sage: S=H([0,-1,1,0])
458
+ sage: S._acton_complex_plane_element(z)
459
+ [1.00000000000000*I, 1.00000000000000*I]
460
+
461
+
462
+ """
463
+ result = []
464
+ if len(z) != len(self.complex_embeddings()):
465
+ raise ValueError("Need element of the same degree!")
466
+ for i, Aemb in enumerate(self.complex_embeddings()):
467
+ a, b, c, d = Aemb.list()
468
+ result.append((a*z[i] + b)/(c*z[i]+d))
469
+ return z.parent()(result)
470
+
471
+ def __getitem__(self, q):
472
+ r"""
473
+ Fetch entries by direct indexing.
474
+
475
+ EXAMPLES::
476
+
477
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
478
+ sage: H=HilbertModularGroup(5)
479
+ sage: H([3,2,1,1])[0,0]
480
+ 3
481
+ """
482
+ return self.__x[q]
483
+
484
+ def __hash__(self):
485
+ r"""
486
+ Return a hash value.
487
+
488
+ EXAMPLES::
489
+
490
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
491
+ sage: H=HilbertModularGroup(5)
492
+ sage: x,y=H.base_ring().gens()
493
+ sage: A = H([1,x,x,x+2]); hash(A)
494
+ -3779633680309204004
495
+ """
496
+ return hash(self.__x)
497
+
498
+ def __reduce__(self):
499
+ r"""
500
+ Used for pickling.
501
+
502
+ EXAMPLES::
503
+
504
+ sage: (SL2Z.1).__reduce__()
505
+ (Modular Group SL(2,Z), (
506
+ [1 1]
507
+ [0 1]
508
+ ))
509
+ """
510
+ return self.parent(), (self.__x,)
511
+
512
+ def trace(self):
513
+ r"""
514
+ Return the trace of the trace of the matrix of self.
515
+
516
+ EXAMPLES::
517
+
518
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
519
+ sage: H=HilbertModularGroup(5)
520
+ sage: x,y=H.base_ring().gens()
521
+ sage: A = H([1,x,x,x+2]); A
522
+ [ 1 1/2*a + 1/2]
523
+ [1/2*a + 1/2 1/2*a + 5/2]
524
+ sage: A.matrix().trace()
525
+ 1/2*a + 7/2
526
+ sage: A.trace()
527
+ 7
528
+
529
+ """
530
+ return self.matrix().trace().trace()
531
+
532
+ def multiplicative_order(self, check=True):
533
+ r"""
534
+ Return the multiplicative order of this element.
535
+
536
+ EXAMPLES::
537
+
538
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
539
+ sage: H=HilbertModularGroup(5)
540
+ sage: H.one().multiplicative_order()
541
+ 1
542
+ sage: H([-1,0,0,-1]).multiplicative_order()
543
+ 2
544
+ sage: H([0,-1,1,0]).multiplicative_order()
545
+ 4
546
+ sage: H([0,-1,1,1]).multiplicative_order()
547
+ 6
548
+ sage: H([1,1,0,1]).multiplicative_order()
549
+ +Infinity
550
+ sage: x,y=H.base_ring().gens()
551
+ sage: A = H([0,x**-1,-x,0]); A
552
+ [ 0 1/2*a - 1/2]
553
+ [-1/2*a - 1/2 0]
554
+ sage: A.multiplicative_order()
555
+ 4
556
+ sage: A=H([0,-1,1,x]); A
557
+ [ 0 -1]
558
+ [ 1 1/2*a + 1/2]
559
+ sage: A.multiplicative_order()
560
+ 10
561
+ sage: A = H([1,x,x,x+2]); A
562
+ [ 1 1/2*a + 1/2]
563
+ [1/2*a + 1/2 1/2*a + 5/2]
564
+ sage: A.multiplicative_order()
565
+ +Infinity
566
+
567
+ """
568
+ m = self.matrix()
569
+ if m.is_one():
570
+ return ZZ(1)
571
+ elif (-m).is_one():
572
+ return ZZ(2)
573
+ t = m.trace()
574
+ # We check if t is in the list of possible orders for this number field
575
+ order = self.parent().order_of_elliptic_element_of_trace(t)
576
+ if check:
577
+ max_order = order or max(self.parent().orders_of_elliptic_elements())
578
+ for i in range(2,max_order+1):
579
+ m = m*self.matrix()
580
+ if m.is_one() and (not order or (i < order or not m.is_one() and i == order)):
581
+ raise ArithmeticError("Could not find order of element!")
582
+ if not order:
583
+ return infinity
584
+ return order
585
+
586
+ @cached_method
587
+ def complex_embeddings(self, prec=53):
588
+ """
589
+ Return a list of matrices which are entry-wise complex embeddings of self
590
+
591
+ INPUT:
592
+ - ``prec`` integer (default=53) number of bits precision
593
+
594
+ EXAMPLES::
595
+
596
+ sage: from hilbert_modgroup.hilbert_modular_group_class import HilbertModularGroup
597
+ sage: H=HilbertModularGroup(5)
598
+ sage: x,y=H.base_ring().gens()
599
+ sage: A = H([0,x**-1,-x,0]); A
600
+ [ 0 1/2*a - 1/2]
601
+ [-1/2*a - 1/2 0]
602
+ sage: A.complex_embeddings()
603
+ [
604
+ [0.000000000000000 -1.61803398874989]
605
+ [0.618033988749895 0.000000000000000],
606
+ [0.000000000000000 0.618033988749895]
607
+ [-1.61803398874989 0.000000000000000]
608
+ ]
609
+ sage: A.complex_embeddings(103)
610
+ [
611
+ [0.000000000000000000000000000000 -1.61803398874989484820458683437]
612
+ [0.618033988749894848204586834366 0.000000000000000000000000000000],
613
+ [0.000000000000000000000000000000 0.618033988749894848204586834366]
614
+ [-1.61803398874989484820458683437 0.000000000000000000000000000000]
615
+ ]
616
+ """
617
+ emb_a = self.a().complex_embeddings(prec)
618
+ emb_b = self.b().complex_embeddings(prec)
619
+ emb_c = self.c().complex_embeddings(prec)
620
+ emb_d = self.d().complex_embeddings(prec)
621
+ M = MatrixSpace(emb_a[0].parent(),2,2)
622
+ return [ M([emb_a[i], emb_b[i], emb_c[i], emb_d[i]]) for i in range(len(emb_a))]
623
+