Skip to content

Commit 743c6ba

Browse files
committed
Fixed a bug introduced when trying to reduce the calls to word_rep.
1 parent 155860b commit 743c6ba

9 files changed

+38
-115
lines changed

README.rst

-12
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,6 @@ This returns something like::
7979

8080
3) A curve over a cubic field of mixed signature::
8181

82-
sage: F.<r> = NumberField(x^3-x^2-x+2)
83-
sage: N = F.ideal(r^2 + 2)
84-
sage: P = N.factor()[0][0]
85-
sage: D = N/P
86-
sage: find_curve(P,D,N,20)
87-
88-
which returns::
89-
90-
y^2 + x*y + y = x^3 + (r^2-2)*x^2 + (r^2-2)*x + (-r^2-r)
91-
92-
4) Another (more spectacular) curve over a cubic field of mixed signature::
93-
9482
sage: F.<r> = NumberField(x^3 -3)
9583
sage: P = F.ideal(r-2)
9684
sage: D = F.ideal(r-1)

arithgroup.py

+15-13
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,14 @@ def one(self):
109109
def _element_constructor_(self,x):
110110
if isinstance(x,list):
111111
return self.element_class(self, word_rep = x,check = False)
112-
elif x.parent() is self.quaternion_algebra():
113-
return self.element_class(self, quaternion_rep = x,check = False)
114112
elif isinstance(x, self.element_class):
115-
if not x.has_word_rep:
113+
if x.parent() is self:
114+
if x.has_word_rep:
115+
word_rep = x.word_rep
116+
else:
117+
word_rep = None
118+
return self.element_class(self, quaternion_rep = x.quaternion_rep, word_rep = word_rep, check = False)
119+
elif not x.has_word_rep:
116120
return self.element_class(self, quaternion_rep = x.quaternion_rep, word_rep = None, check = False)
117121
else:
118122
word_rep = []
@@ -121,7 +125,7 @@ def _element_constructor_(self,x):
121125
if a > 0:
122126
word_rep += self.get_word_rep(Gx.gen(i).quaternion_rep) * a
123127
else:
124-
word_rep += self.get_word_rep(Gx.gen(i).quaternion_rep**-1) * (-a)
128+
word_rep += [(i,-b) for i,b in reversed(self.get_word_rep(Gx.gen(i).quaternion_rep))] * (-a)
125129
ans = self.element_class(self, quaternion_rep = x.quaternion_rep, word_rep = word_rep, check = False)
126130
return ans
127131
elif isinstance(x.parent(),FreeModule_generic):
@@ -272,14 +276,13 @@ def get_hecke_ti(self,gk1,gamma,l,use_magma):
272276
- t_{gk1}(gamma)
273277
274278
"""
275-
elt = gk1**-1 * gamma
279+
elt = gk1**-1 * gamma.quaternion_rep
276280
reps = self.get_hecke_reps(l,use_magma = use_magma)
277281
for gk2 in reps:
278282
ti = elt * gk2
279283
is_in_order = self._is_in_order(ti)
280284
if self._is_in_order(ti):
281-
ans = self(ti)
282-
return ans
285+
return self(ti)
283286
verbose("ti not found. gk1 = %s, gamma = %s, l = %s"%(gk1,gamma,l))
284287
raise RuntimeError("ti not found. gk1 = %s, gamma = %s, l = %s"%(gk1,gamma,l))
285288

@@ -297,7 +300,7 @@ def get_Up_ti(self,gk1,gamma):
297300
- t_{gk1}(gamma)
298301
299302
"""
300-
elt = gk1**-1 * gamma
303+
elt = gk1**-1 * gamma.quaternion_rep
301304
reps = self.get_Up_reps()
302305
for gk2 in reps:
303306
ti = elt * gk2
@@ -321,7 +324,7 @@ def hecke_matrix(self,l,use_magma = True,g0 = None):
321324
V = QQ**len(gens)
322325
for j,g in enumerate(gens):
323326
# Construct column j of the matrix
324-
newcol = sum([V(list(Gab.G_to_ab(self.get_hecke_ti(gk1,Gab.ab_to_G(g).quaternion_rep,l,use_magma)))) for gk1 in hecke_reps],V(0))
327+
newcol = sum([V(list(Gab.G_to_ab(self.get_hecke_ti(gk1,Gab.ab_to_G(g),l,use_magma)))) for gk1 in hecke_reps],V(0))
325328
M.set_column(j,list(newcol))
326329
return M
327330

@@ -335,7 +338,7 @@ def hecke_matrix_freepart(self,l,use_magma = True,g0 = None):
335338
V = QQ**len(freegens)
336339
for j,g in enumerate(freegens):
337340
# Construct column j of the matrix
338-
glift = Gab.ab_to_G(g).quaternion_rep
341+
glift = Gab.ab_to_G(g)
339342
newcol = list(Gab.G_to_ab_free(prod([self.get_hecke_ti(gk1,glift,l,use_magma) for gk1 in hecke_reps],self.one())))
340343
M.set_column(j,newcol)
341344
return M
@@ -350,8 +353,7 @@ def involution_at_infinity_matrix_freepart(self,use_magma = True):
350353
V = QQ**len(freegens)
351354
for j,g in enumerate(freegens):
352355
# Construct column j of the matrix
353-
glift = Gab.ab_to_G(g).quaternion_rep
354-
newg = self(x**-1 * glift * x)
356+
newg = Gab.ab_to_G(g).conjugate_by(x)
355357
M.set_column(j,list(Gab.G_to_ab_free(newg)))
356358
return M
357359

@@ -959,7 +961,7 @@ def get_word_rep(self,delta):
959961
ans = list(self._Gamma0_farey.word_problem(SL2Z(delta.list()),output = 'standard'))
960962
tmp = self.B(1)
961963
for i,a in shorten_word(ans):
962-
tmp = tmp * self.gen(i).quaternion_rep**a
964+
tmp *= self.gen(i).quaternion_rep**a
963965
delta = SL2Z(delta.list())
964966
err = SL2Z(delta * SL2Z(tmp**-1))
965967
I = SL2Z([1,0,0,1])

arithgroup_element.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ def __init__(self,parent, word_rep = None, quaternion_rep = None, check = False)
3838
an element of the quaternion algebra ``self.parent().quaternion_algebra()``
3939
'''
4040
MultiplicativeGroupElement.__init__(self, parent)
41-
# check = True #DEBUG
4241
init_data = False
4342
self.has_word_rep = False
4443
self.has_quaternion_rep = False
@@ -68,14 +67,11 @@ def __init__(self,parent, word_rep = None, quaternion_rep = None, check = False)
6867
init_data = True
6968
if init_data is False:
7069
raise ValueError('Must pass either quaternion_rep or word_rep')
71-
# assert self.has_quaternion_rep
72-
# if not self.has_word_rep:
73-
# self.word_rep = self._word_rep()
7470
self._reduce_word()
7571

7672
@cached_method
7773
def __hash__(self):
78-
return self.quaternion_rep.__hash__()
74+
return hash((hash(self.parent()), hash(self.quaternion_rep)))
7975

8076
def _repr_(self):
8177
return str(self.quaternion_rep)
@@ -181,6 +177,7 @@ def __getitem__(self,n):
181177

182178
@cached_method
183179
def embed(self,prec):
180+
assert self.has_quaternion_rep
184181
return self.parent().embed(self.quaternion_rep,prec)
185182

186183
def conjugate_by(self, wp):

cohomology.py

+6-9
Original file line numberDiff line numberDiff line change
@@ -243,20 +243,18 @@ def _evaluate_syllable(self,g,a):
243243
V = self.parent().coefficient_module()
244244
prec = V.precision_cap()
245245
Sigma0 = self.parent().Sigma0()
246-
#G._evaluate_stats[ZZ(a).abs()] += 1
247246
if a == 1:
248247
return self._val[g]
249248
elif a == 0:
250249
return V(0)
251250
elif a == -1:
252-
# gmat_inv = G.embed(G.gen(g).quaternion_rep**-1,prec)
253251
gmat_inv = G.gen(g).embed(prec).adjoint() # G.gen(g).embed(prec)**-1
254252
if self.parent()._use_ps_dists:
255253
return -(Sigma0(gmat_inv) * self._val[g])
256254
else:
257255
return -self._val[g].l_act_by(gmat_inv)
258256
elif a < 0:
259-
gmat = G.gen(g).embed(prec) # G.embed(G.gen(g).quaternion_rep,prec)
257+
gmat = G.gen(g).embed(prec)
260258
gmat_inv = gmat.adjoint() #gmat**-1
261259
phig = self._val[g]
262260
tmp = V(phig)
@@ -269,7 +267,7 @@ def _evaluate_syllable(self,g,a):
269267
tmp = phig + tmp.l_act_by(gmat)
270268
return -(tmp.l_act_by(gmat_inv**-a))
271269
else:
272-
gmat = G.gen(g).embed(prec) #G.embed(G.gen(g).quaternion_rep,prec)
270+
gmat = G.gen(g).embed(prec)
273271
phig = self._val[g]
274272
tmp = V(phig)
275273
if self.parent()._use_ps_dists:
@@ -590,7 +588,7 @@ def involution_at_infinity_matrix(self):
590588
assert len(self.gens()) == len(Gab.free_gens())
591589
for j,g0 in enumerate(Gab.free_gens()):
592590
# Construct column j of the matrix
593-
g = Gpn(x**-1 * Gab.ab_to_G(g0).quaternion_rep * x)
591+
g = Gab.ab_to_G(g0).conjugate_by(x)
594592
M.set_column(j,list(Gab.G_to_ab_free(g)))
595593
return M.transpose()
596594

@@ -942,7 +940,7 @@ def apply_hecke_operator(self,c,l, hecke_reps = None,group = None,scale = 1,use_
942940
input_vector = []
943941
# verbose('Calculating action')
944942
for j,gamma in enumerate(gammas):
945-
input_vector.extend([(group,g,gamma.quaternion_rep,c,l,hecke_reps,padic,S0(Gpn.embed(g,prec)),self._use_ps_dists,use_magma,j) for g in hecke_reps])
943+
input_vector.extend([(group,g,gamma,c,l,hecke_reps,padic,S0(Gpn.embed(g,prec)),self._use_ps_dists,use_magma,j) for g in hecke_reps])
946944
if parallelize:
947945
f = parallel(_calculate_hecke_contribution)
948946
for inp,outp in f(input_vector):
@@ -1000,7 +998,7 @@ def apply_Up(self,c,group = None,scale = 1,parallelize = False,times = 0,progres
1000998
vals = [V(0) for gamma in gammas]
1001999
input_vector = []
10021000
for j,gamma in enumerate(gammas):
1003-
input_vector.extend([(group,g,gamma.quaternion_rep,c,repslocal[k],self._use_ps_dists,j) for k,g in enumerate(Up_reps)])
1001+
input_vector.extend([(group,g,gamma,c,repslocal[k],self._use_ps_dists,j) for k,g in enumerate(Up_reps)])
10041002
if parallelize:
10051003
f = parallel(_calculate_Up_contribution)
10061004
for inp,outp in f(input_vector):
@@ -1028,8 +1026,7 @@ def apply_Up(self,c,group = None,scale = 1,parallelize = False,times = 0,progres
10281026
counter = 0
10291027
iS = 0
10301028
for i,gi in enumerate(self.group().gens()):
1031-
giquat = gi.quaternion_rep
1032-
ti = [tuple(self.group().get_Up_ti(sk,giquat).word_rep) for sk in Up_reps]
1029+
ti = [tuple(self.group().get_Up_ti(sk,gi).word_rep) for sk in Up_reps]
10331030
jS = 0
10341031
for ans in find_newans(self,repslocal,ti):
10351032
A.set_block(iS,jS,ans)

findcurve.sage

-9
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,8 @@ def find_curve(P, DB, NE, prec, sign_ap = 1, magma = None, return_all = False, i
2121
sage: D = F.ideal(3)
2222
sage: find_curve(P,D,P*D,30,ramification_at_infinity = F.real_places()[:1])
2323
24-
2524
Now over a cubic of mixed signature::
2625
27-
sage: F.<r> = NumberField(x^3-x^2-x+2)
28-
sage: N = F.ideal(r^2 + 2)
29-
sage: P = N.factor()[0][0]
30-
sage: D = N/P
31-
sage: find_curve(P,D,N,20)
32-
33-
And another one::
34-
3526
sage: F.<r> = NumberField(x^3 -3)
3627
sage: P = F.ideal(r-2)
3728
sage: D = F.ideal(r-1)

homology.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ def _call_(self,g,v):
326326
return v.parent()(v)
327327
prec = K.precision_cap()
328328
G = g.parent()
329-
a,b,c,d = [K(o) for o in G.embed(g.quaternion_rep,prec).list()] #G.embed(g.quaternion_rep,prec).change_ring(K).list()
329+
a,b,c,d = [K(o) for o in G.embed(g.quaternion_rep,prec).list()]
330330
newdict = defaultdict(ZZ)
331331
newpts = {}
332332
for P,n in v:
@@ -494,17 +494,16 @@ def factor_into_generators(self,prec):
494494
newv = v
495495
for i,a in gword:
496496
g = G.gen(i)
497-
gq = g.quaternion_rep
498497
oldv = newv
499-
newv = oldv.left_act_by_matrix(G.embed(gq**-a,prec))
498+
newv = g**-a * oldv
500499
sign = 1
501500
if a < 0:
502501
a = -a
503-
oldv = oldv.left_act_by_matrix(G.embed(gq**a,prec))
502+
oldv = g**a * oldv
504503
sign = -1
505504
for j in range(a):
506505
newdict[g] += sign * oldv
507-
oldv = oldv.left_act_by_matrix(G.embed(gq**-1,prec))
506+
oldv = g**-1 * oldv
508507
if a > 0:
509508
assert oldv == newv
510509
return HomologyClass(self.parent(),newdict)
@@ -537,7 +536,7 @@ def act_by_hecke(self,l,prec,g0 = None):
537536
hecke_reps = G.get_hecke_reps(l,g0 = g0)
538537
for gk1 in hecke_reps:
539538
for g,v in self._data.iteritems():
540-
ti = G.get_hecke_ti(gk1,g.quaternion_rep,l,True)
539+
ti = G.get_hecke_ti(gk1,g,l,True)
541540
gk1inv = gk1**-1
542541
set_immutable(gk1inv)
543542
newv = v.left_act_by_matrix(G.embed(gk1inv,prec))

homology_abstract.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def act_by_hecke(self,l,prec):
100100
hecke_reps = G.get_hecke_reps(l)
101101
for gk1 in hecke_reps:
102102
for g,v in self._data.iteritems():
103-
ti = G.get_hecke_ti(gk1,g.quaternion_rep,l,hecke_reps)
103+
ti = G.get_hecke_ti(gk1,g,l,hecke_reps)
104104
newv = v.left_act_by_matrix(G.embed(gk1**-1,prec))
105105
try:
106106
newdict[ti] += newv

integrals.py

+6-13
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,12 @@ def integrate_H1(G,cycle,cocycle,depth = 1,method = 'moments',prec = None,parall
161161
resadd = Cp(0)
162162
for g,divisor in cycle.get_data():
163163
jj += 1
164-
gq = g.quaternion_rep
165164
if divisor.degree() != 0:
166-
verbose('Divisor must be of degree 0. Now it is of degree %s. And g = %s.'%(divisor.degree(),gq))
167-
continue
168-
raise ValueError('Divisor must be of degree 0. Now it is of degree %s. And g = %s.'%(divisor.degree(),gq))
165+
raise ValueError('Divisor must be of degree 0. Now it is of degree %s. And g = %s.'%(divisor.degree(),g.quaternion_rep))
169166
if twist:
170167
divisor = divisor.left_act_by_matrix(G.embed(G.wp(),prec).change_ring(Cp))
171-
gq = G.wp() * gq * G.wp()**-1
172-
newres,newresadd = integrate_H0(G,divisor,cocycle,depth,gq,prec,jj,total_integrals,progress_bar,parallelize,multiplicative)
168+
g = g.conjugate_by(G.wp()**-1)
169+
newres,newresadd = integrate_H0(G,divisor,cocycle,depth,g,prec,jj,total_integrals,progress_bar,parallelize,multiplicative)
173170
res *= newres
174171
resadd += newresadd
175172
if not multiplicative:
@@ -262,7 +259,7 @@ def integrate_H0_riemann(G,divisor,hc,depth,gamma,prec,counter,total_counter,pro
262259
R = PolynomialRing(K,names = 't').fraction_field()
263260
t = R.gen()
264261
phi = prod([(t - P)**ZZ(n) for P,n in divisor],R(1))
265-
return riemann_sum(G,phi,hc.shapiro_image(G)(gamma),depth,mult = multiplicative)
262+
return riemann_sum(G,phi,hc.shapiro_image(G)(gamma.quaternion_rep),depth,mult = multiplicative)
266263

267264
def integrate_H0_moments(G,divisor,hc,depth,gamma,prec,counter,total_counter,progress_bar,parallelize,multiplicative):
268265
# verbose('Integral %s/%s...'%(counter,total_counter))
@@ -310,13 +307,9 @@ def integrate_H0_moments(G,divisor,hc,depth,gamma,prec,counter,total_counter,pro
310307
newedgelist.extend([(parity,o,wt/QQ(p**2)) for o in G.subdivide([edge],parity,2)])
311308
continue
312309
if not rev:
313-
newgamma = G.reduce_in_amalgam(h * gamma)
310+
newgamma = G.reduce_in_amalgam(h * gamma.quaternion_rep)
314311
else:
315-
newgamma = G.wp()**-1 * G.reduce_in_amalgam(h * gamma) * G.wp()
316-
try:
317-
newgamma.set_immutable()
318-
except AttributeError:
319-
pass
312+
newgamma = G.reduce_in_amalgam(h * gamma.quaternion_rep).conjugate_by(G.wp())
320313
if HOC._use_ps_dists:
321314
mu_e = hc.evaluate(newgamma,parallelize)
322315
resadd += sum(a*mu_e.moment(i) for a,i in izip(pol.coefficients(),pol.exponents()) if i < len(mu_e._moments))

0 commit comments

Comments
 (0)