Closed saraedum closed 2 years ago
Currently, the implementation reads
e0,e1 = r.change_ring(CDF).eigenvalues()
m0 = (e0.log() / 2 / CDF.pi()).imag()
m1 = (e1.log() / 2 / CDF.pi()).imag()
r0 = RR(m0).nearby_rational(max_denominator=10000)
r1 = RR(m1).nearby_rational(max_denominator=10000)
if r0 != -r1:
raise RuntimeError
r0 = r0.abs()
if r[0][1] > 0:
return QQ.one() - r0
else:
return r0
if check:
e = r.change_ring(AA).eigenvalues()[0]
if e.minpoly() != ZZ['x'].cyclotomic_polynomial()(r.denominator()):
raise RuntimeError
z = QQbar.zeta(r.denominator())
if z**r.numerator() != e:
raise RuntimeError
return r
Curiously, the check
part is never executed.
I think I prefer to use tr(R) = 1 + 2cos α
. I.e., compute an arccos, pick the sign and approximate as a rational. Any reason the current implementation is better? @videlec
Hm…more importantly, this method is not used anywhere.
In some setups we get a