SharedMRC-Traingle Groups / Traces_2-3-13.sagewsOpen in CoCalc
A = matrix([[0,1], [-1,0]])
B= matrix([[1/2, -cos(pi/13) - (1/2) *sqrt(-3 + 4*cos(pi/13)^2)],[3/(2*(2*cos(pi/13)+ sqrt(-3 + 4*cos(pi/13)^2))), 1/2]])

print A
print A.trace()
print B.trace()
print A*B
print A.trace()


[ 0 1] [-1 0] 0 1 [3/2/(sqrt(4*cos(1/13*pi)^2 - 3) + 2*cos(1/13*pi)) 1/2] [ -1/2 1/2*sqrt(4*cos(1/13*pi)^2 - 3) + cos(1/13*pi)] 0
eval('A*B', {'A': A, 'B':B})

[3/2/(sqrt(4*cos(1/13*pi)^2 - 3) + 2*cos(1/13*pi)) 1/2] [ -1/2 1/2*sqrt(4*cos(1/13*pi)^2 - 3) + cos(1/13*pi)]
from string import translate, maketrans
flip = maketrans('aA','Aa')

class fraction:
def __init__(self, num, den):
self.num, self.den = num, den
def numerator(self):
return self.num
def denominator(self):
return self.den
def __eq__(self, other):
return ( self.numerator() == other.numerator() and
self.denominator() == other.denominator() )
def __repr__(self):
return '%d/%d'%(self.num, self.den)

oo = fraction(1,0)
_oo = fraction(-1,0)
_0 = fraction(0,-1)

def E(farey):
"""
Given a Farey fraction p/q (including oo=1/0), return a primitive
element of the rank 2 free group in the conjugacy class determined
by the fraction, expressed either as a palindrome (if pq is even
for p/q reduced) or as a product of two palindromes.  The
primitive elements are only defined up to taking inverses so, by
convention, the result is either a word in the letters a and B, or
A and B.

Usage example:

sage: %attach palindromes.py
sage: E(0)
'a'
sage: E(oo)
'B'
sage: E(1)
'aB'
sage: E(-1)
'B.A'
sage: E(2/3)
'aBaBa'
sage: E(4/6)
'aBaBa'
sage: E(3/5)
'aBa.aBaBa'
sage: E(19/11)
'BaBBaBaBBaBBaBaBBaB.BaBBaBaBBaB'
sage: E(-19/11)
'BABBABABBAB.BABBABABBABBABABBAB'
'BBaBBBaBBBBaBBBaBBBaBBBBaBBBaBB

"""
if oo == farey:
return 'B'
elif _oo == farey:
return 'B'
elif _0 == farey:
return 'A'
elif 0 == farey:
return 'a'
#put the fraction in standard form:
p, q = farey.numerator(), farey.denominator()
x = p/q
p, q = x.numerator(), x.denominator()
if q == 1:
if p > 0:
smaller, larger = (p-1)/1, oo
else:
smaller, larger = _oo, (p+1)/1
else:
cf_list = list(continued_fraction(x))
front = continued_fraction(cf_list[:-1])
cf_list[-1] -= 1
back = continued_fraction(cf_list)
neighbors = [front.value(), back.value()]
neighbors.sort()
smaller, larger = neighbors
if larger.numerator() == 0:
larger = _0
if p*q % 2 == 0:
return E(larger).replace('.','') + '*'+  E(smaller).replace('.','')
else:
return E(smaller).replace('.','') + '*'+E(larger).replace('.','')

#q will be the denominator, p will be the numerator
L = [] #List of traces
for a in range(11):
for b in range(a):
if gcd(a,b)== 1:
L.append(abs(eval(E(a/(b+1)) , {'A':A, 'B': B, 'a': A^(-1)}).trace()).simplify_full())
T = uniq(L) #List of unique traces
for j in range(len(T)):
T[j] = RR(T[j])
print T


[0.000000000000000, 1.00000000000000, 1.94188363485210, 2.77091205130642, 3.43890513119431, 3.43890513119430, 3.90704154476873, 4.14811490527937, 4.14811490527939, 7.58702003647368]


#print the number of traces which occur in an interval
Num = []
for n in range(10):
c = 0
for j in range(len(T)):
if T[j] >= n and T[j]< n+1:
c +=1
Num.append(c)
list_plot(Num)