def flipper_nf_to_sage(K, name='a'): r""" Convert a flipper number field into a Sage number field .. NOTE:: Currently, the code is not careful at all with root isolation. EXAMPLES:: sage: import flipper # optional - flipper sage: from flatsurf.geometry.similarity_surface_generators import flipper_nf_to_sage sage: p = flipper.kernel.Polynomial([-2r] + [0r]*5 + [1r]) # optional - flipper sage: r1,r2 = p.real_roots() # optional - flipper sage: K = flipper.kernel.NumberField(r1) # optional - flipper sage: K_sage = flipper_nf_to_sage(K) # optional - flipper sage: K_sage # optional - flipper Number Field in a with defining polynomial x^6 - 2 sage: AA(K_sage.gen()) # optional - flipper -1.122462048309373? """ from sage.rings.number_field.number_field import NumberField from sage.rings.all import QQ,RIF,AA r = K.lmbda.interval_approximation() l = r.lower * ZZ(10)**(-r.precision) u = r.upper * ZZ(10)**(-r.precision) p = QQ['x'](K.polynomial.coefficients) s = AA.polynomial_root(p, RIF(l,u)) return NumberField(p, name, embedding=s)
def flipper_nf_to_sage(K, name='a'): r""" Convert a flipper number field into a Sage number field .. NOTE:: Currently, the code is not careful at all with root isolation. EXAMPLES:: sage: import flipper # optional - flipper sage: import realalg # optional - flipper sage: from flatsurf.geometry.similarity_surface_generators import flipper_nf_to_sage sage: K = realalg.RealNumberField([-2r] + [0r]*5 + [1r]) # optional - flipper sage: K_sage = flipper_nf_to_sage(K) # optional - flipper sage: K_sage # optional - flipper Number Field in a with defining polynomial x^6 - 2 with a = 1.122462048309373? sage: AA(K_sage.gen()) # optional - flipper 1.122462048309373? """ r = K.lmbda.interval() l = r.lower * ZZ(10)**(-r.precision) u = r.upper * ZZ(10)**(-r.precision) p = QQ['x'](K.coefficients) s = AA.polynomial_root(p, RIF(l, u)) return NumberField(p, name, embedding=s)
def number_field_to_AA(a): r""" It is a mess to convert an element of a number field to the algebraic field ``AA``. This is a temporary fix. """ try: return AA(a) except TypeError: return AA.polynomial_root(a.minpoly(), RIF(a))
def from_mathematica(a): try: return QQ(a.sage()) except Exception: pass try: return AA(a.sage()) except Exception: coefficients = mathematica.CoefficientList( mathematica.MinimalPolynomial(a, 'x'), 'x').sage() x = polygen(QQ) minpoly = x.parent()(coefficients) interval = mathematica.IsolatingInterval(a).sage() rif_interval = RIF(interval) return AA.polynomial_root(minpoly, rif_interval)
- 251568270025211201955389171860338579171675714868104052152789880989805712726614197574887246767925108246607970007160940134370673529705101398997875679835167365081669374673539993436160000*t**3 - 141772430429024326881509616736177148212059744813752208473666088996700368688933789363560771135161864201721524861419389136852260702560567771393655430337183040528733205980885277265100800000*t**2 - 25817606346086956476758470208850883766420383787607030339022713274189365873405154695767797745935894060883806800961601773820707673481632102376182116930107064769426021006200320503617211596800*t + 34918206405098505823938790072675572231488655998026261577866691497637535623661745400444768148106948876570405151317417742685700849593772165309178580940805695949542187927076864000)*Dt) quadric_slice_pol = ( 4980990673427087034113103774848375913397675011396681161337606780457883155824640000000000*t**12 - 16313074573215242896867677175985719375664055250377801991087546344967331905536000000000*t**9 - 14852779293587242300314544658084523021409425155052443959294262319432698489552764928000000*t**8 + 18694126910889886952945780127491545129704079293214429569400282861674612412907520000*t**6 + 32429224374768702788524801575483580065598417846595577296275963028007688596147404800000*t**5 + 14763130935033327878568955564665179022508855828282305094488782847988800598441515915673600*t**4 - 7447056930374930458107131157447569387299331973073657492405996702806537404416000*t**3 - 18581243794708202636835504417848386599346688512251081679746508518773002589362454528*t**2 - 16116744082275656666424675660780874575937043631040306492377025123023286892432343685120*t - 4891341219838850087826096307272910719484535278552470341569283855964428449539674077056375) quadric_slice_crit = AA.polynomial_root(quadric_slice_pol, RIF(-0.999,-0.998)) aa = AA.polynomial_root(AA.common_polynomial(t**2 - t - 6256320), RIF(-RR(2500.7637305969961), -RR(2500.7637305969956))) K, a = NumberField(t**2 - t - 6256320, 'a', embedding=aa).objgen() DiffOps_x, x, Dx = DifferentialOperators(K, 'x') iint_quadratic_alg = IVP( dop = ( (8680468749131953125000000000000000000000*x**13 + (34722222218750000000000000000000*a - 8680555572048611109375000000000000000000)*x**12 - 43419899820094632213834375000000000000000*x**11 + ( -173681336093739466250000000000000*a + 43420334110275534609369733125000000000000)*x**10 + 86874920665761352031076792873375000000000*x**9 + (347503157694622354347850650000000*a
def arnoux_yoccoz(genus): r""" Construct the Arnoux-Yoccoz surface of genus 3 or greater. This presentation of the surface follows Section 2.3 of Joshua P. Bowman's paper "The Complete Family of Arnoux-Yoccoz Surfaces." EXAMPLES:: sage: from flatsurf import * sage: s = translation_surfaces.arnoux_yoccoz(4) sage: TestSuite(s).run() sage: s.is_delaunay_decomposed() True sage: s = s.canonicalize() sage: field=s.base_ring() sage: a = field.gen() sage: from sage.matrix.constructor import Matrix sage: m = Matrix([[a,0],[0,~a]]) sage: ss = m*s sage: ss = ss.canonicalize() sage: s.cmp_translation_surface(ss)==0 True The Arnoux-Yoccoz pseudo-Anosov are known to have (minimal) invariant foliations with SAF=0:: sage: S3 = translation_surfaces.arnoux_yoccoz(3) sage: Jxx, Jyy, Jxy = S3.j_invariant() sage: Jxx.is_zero() and Jyy.is_zero() True sage: Jxy [ 0 2 0] [ 2 -2 0] [ 0 0 2] sage: S4 = translation_surfaces.arnoux_yoccoz(4) sage: Jxx, Jyy, Jxy = S4.j_invariant() sage: Jxx.is_zero() and Jyy.is_zero() True sage: Jxy [ 0 2 0 0] [ 2 -2 0 0] [ 0 0 2 2] [ 0 0 2 0] """ g=ZZ(genus) assert g>=3 from sage.rings.polynomial.polynomial_ring import polygen x = polygen(AA) p=sum([x**i for i in xrange(1,g+1)])-1 cp = AA.common_polynomial(p) alpha_AA = AA.polynomial_root(cp, RIF(1/2, 1)) field=NumberField(alpha_AA.minpoly(),'alpha',embedding=alpha_AA) a=field.gen() from sage.modules.free_module import VectorSpace V=VectorSpace(field,2) p=[None for i in xrange(g+1)] q=[None for i in xrange(g+1)] p[0]=V(( (1-a**g)/2, a**2/(1-a) )) q[0]=V(( -a**g/2, a )) p[1]=V(( -(a**(g-1)+a**g)/2, (a-a**2+a**3)/(1-a) )) p[g]=V(( 1+(a-a**g)/2, (3*a-1-a**2)/(1-a) )) for i in xrange(2,g): p[i]=V(( (a-a**i)/(1-a) , a/(1-a) )) for i in xrange(1,g+1): q[i]=V(( (2*a-a**i-a**(i+1))/(2*(1-a)), (a-a**(g-i+2))/(1-a) )) from flatsurf.geometry.polygon import Polygons P=Polygons(field) s = Surface_list(field) T = [None] * (2*g+1) Tp = [None] * (2*g+1) from sage.matrix.constructor import Matrix m=Matrix([[1,0],[0,-1]]) for i in xrange(1,g+1): # T_i is (P_0,Q_i,Q_{i-1}) T[i]=s.add_polygon(P(edges=[ q[i]-p[0], q[i-1]-q[i], p[0]-q[i-1] ])) # T_{g+i} is (P_i,Q_{i-1},Q_{i}) T[g+i]=s.add_polygon(P(edges=[ q[i-1]-p[i], q[i]-q[i-1], p[i]-q[i] ])) # T'_i is (P'_0,Q'_{i-1},Q'_i) Tp[i]=s.add_polygon(m*s.polygon(T[i])) # T'_{g+i} is (P'_i,Q'_i, Q'_{i-1}) Tp[g+i]=s.add_polygon(m*s.polygon(T[g+i])) for i in xrange(1,g): s.change_edge_gluing(T[i],0,T[i+1],2) s.change_edge_gluing(Tp[i],2,Tp[i+1],0) for i in xrange(1,g+1): s.change_edge_gluing(T[i],1,T[g+i],1) s.change_edge_gluing(Tp[i],1,Tp[g+i],1) #P 0 Q 0 is paired with P' 0 Q' 0, ... s.change_edge_gluing(T[1],2,Tp[g],2) s.change_edge_gluing(Tp[1],0,T[g],0) # P1Q1 is paired with P'_g Q_{g-1} s.change_edge_gluing(T[g+1],2,Tp[2*g],2) s.change_edge_gluing(Tp[g+1],0,T[2*g],0) # P1Q0 is paired with P_{g-1} Q_{g-1} s.change_edge_gluing(T[g+1],0,T[2*g-1],2) s.change_edge_gluing(Tp[g+1],2,Tp[2*g-1],0) # PgQg is paired with Q1P2 s.change_edge_gluing(T[2*g],2,T[g+2],0) s.change_edge_gluing(Tp[2*g],0,Tp[g+2],2) for i in xrange(2,g-1): # PiQi is paired with Q'_i P'_{i+1} s.change_edge_gluing(T[g+i],2,Tp[g+i+1],2) s.change_edge_gluing(Tp[g+i],0,T[g+i+1],0) s.set_immutable() return TranslationSurface(s)
def mcmullen_genus2_prototype(w, h, t, e, rel=0): r""" McMullen prototypes in the stratum H(2). These prototype appear at least in McMullen "Teichmüller curves in genus two: Discriminant and spin" (2004). The notation from that paper are quadruple ``(a, b, c, e)`` which translates in our notation as ``w = b``, ``h = c``, ``t = a`` (and ``e = e``). The associated discriminant is `D = e^2 + 4 wh`. If ``rel`` is a positive parameter (less than w-lambda) the surface belongs to the eigenform locus in H(1,1). EXAMPLES:: sage: from flatsurf import translation_surfaces sage: from surface_dynamics import AbelianStratum sage: prototypes = { ....: 5: [(1,1,0,-1)], ....: 8: [(1,1,0,-2), (2,1,0,0)], ....: 9: [(2,1,0,-1)], ....: 12: [(1,2,0,-2), (2,1,0,-2), (3,1,0,0)], ....: 13: [(1,1,0,-3), (3,1,0,-1), (3,1,0,1)], ....: 16: [(3,1,0,-2), (4,1,0,0)], ....: 17: [(1,2,0,-3), (2,1,0,-3), (2,2,0,-1), (2,2,1,-1), (4,1,0,-1), (4,1,0,1)], ....: 20: [(1,1,0,-4), (2,2,1,-2), (4,1,0,-2), (4,1,0,2)], ....: 21: [(1,3,0,-3), (3,1,0,-3)], ....: 24: [(1,2,0,-4), (2,1,0,-4), (3,2,0,0)], ....: 25: [(2,2,0,-3), (2,2,1,-3), (3,2,0,-1), (4,1,0,-3)]} sage: for D in sorted(prototypes): ....: for w,h,t,e in prototypes[D]: ....: T = translation_surfaces.mcmullen_genus2_prototype(w,h,t,e) ....: assert T.stratum() == AbelianStratum(2) ....: assert (D.is_square() and T.base_ring() is QQ) or (T.base_ring().polynomial().discriminant() == D) An example with some relative homology:: sage: U8 = translation_surfaces.mcmullen_genus2_prototype(2,1,0,0,1/4) # discriminant 8 sage: U12 = translation_surfaces.mcmullen_genus2_prototype(3,1,0,0,3/10) # discriminant 12 sage: U8.stratum() H_2(1^2) sage: U8.base_ring().polynomial().discriminant() 8 sage: U8.j_invariant() ( [4 0] (0), (0), [0 2] ) sage: U12.stratum() H_2(1^2) sage: U12.base_ring().polynomial().discriminant() 12 sage: U12.j_invariant() ( [6 0] (0), (0), [0 2] ) """ w = ZZ(w) h = ZZ(h) t = ZZ(t) e = ZZ(e) g = w.gcd(h) gg = g.gcd(t).gcd(e) if w <= 0 or h <= 0 or t < 0 or t >= g or not g.gcd(t).gcd( e).is_one() or e + h >= w: raise ValueError("invalid parameters") x = polygen(QQ) poly = x**2 - e * x - w * h if poly.is_irreducible(): emb = AA.polynomial_root(poly, RIF(0, w)) K = NumberField(poly, 'l', embedding=emb) l = K.gen() else: K = QQ D = e**2 + 4 * w * h d = D.sqrt() l = (e + d) / 2 rel = K(rel) # (lambda,lambda) square on top # twisted (w,0), (t,h) s = Surface_list(base_ring=K) if rel: if rel < 0 or rel > w - l: raise ValueError("invalid rel argument") s.add_polygon( polygons(vertices=[(0, 0), (l, 0), (l + rel, l), (rel, l)], ring=K)) s.add_polygon( polygons(vertices=[(0, 0), (rel, 0), (rel + l, 0), (w, 0), (w + t, h), (l + rel + t, h), (t + l, h), (t, h)], ring=K)) s.set_edge_pairing(0, 1, 0, 3) s.set_edge_pairing(0, 0, 1, 6) s.set_edge_pairing(0, 2, 1, 1) s.set_edge_pairing(1, 2, 1, 4) s.set_edge_pairing(1, 3, 1, 7) s.set_edge_pairing(1, 0, 1, 5) else: s.add_polygon( polygons(vertices=[(0, 0), (l, 0), (l, l), (0, l)], ring=K)) s.add_polygon( polygons(vertices=[(0, 0), (l, 0), (w, 0), (w + t, h), (l + t, h), (t, h)], ring=K)) s.set_edge_pairing(0, 1, 0, 3) s.set_edge_pairing(0, 0, 1, 4) s.set_edge_pairing(0, 2, 1, 0) s.set_edge_pairing(1, 1, 1, 3) s.set_edge_pairing(1, 2, 1, 5) s.set_immutable() return TranslationSurface(s)
def arnoux_yoccoz(genus): r""" Construct the Arnoux-Yoccoz surface of genus 3 or greater. This presentation of the surface follows Section 2.3 of Joshua P. Bowman's paper "The Complete Family of Arnoux-Yoccoz Surfaces." EXAMPLES:: sage: from flatsurf import * sage: s = translation_surfaces.arnoux_yoccoz(4) sage: TestSuite(s).run() sage: s.is_delaunay_decomposed() True sage: s = s.canonicalize() sage: field=s.base_ring() sage: a = field.gen() sage: from sage.matrix.constructor import Matrix sage: m = Matrix([[a,0],[0,~a]]) sage: ss = m*s sage: ss = ss.canonicalize() sage: s.cmp(ss) == 0 True The Arnoux-Yoccoz pseudo-Anosov are known to have (minimal) invariant foliations with SAF=0:: sage: S3 = translation_surfaces.arnoux_yoccoz(3) sage: Jxx, Jyy, Jxy = S3.j_invariant() sage: Jxx.is_zero() and Jyy.is_zero() True sage: Jxy [ 0 2 0] [ 2 -2 0] [ 0 0 2] sage: S4 = translation_surfaces.arnoux_yoccoz(4) sage: Jxx, Jyy, Jxy = S4.j_invariant() sage: Jxx.is_zero() and Jyy.is_zero() True sage: Jxy [ 0 2 0 0] [ 2 -2 0 0] [ 0 0 2 2] [ 0 0 2 0] """ g = ZZ(genus) assert g >= 3 x = polygen(AA) p = sum([x**i for i in range(1, g + 1)]) - 1 cp = AA.common_polynomial(p) alpha_AA = AA.polynomial_root(cp, RIF(1 / 2, 1)) field = NumberField(alpha_AA.minpoly(), 'alpha', embedding=alpha_AA) a = field.gen() V = VectorSpace(field, 2) p = [None for i in range(g + 1)] q = [None for i in range(g + 1)] p[0] = V(((1 - a**g) / 2, a**2 / (1 - a))) q[0] = V((-a**g / 2, a)) p[1] = V((-(a**(g - 1) + a**g) / 2, (a - a**2 + a**3) / (1 - a))) p[g] = V((1 + (a - a**g) / 2, (3 * a - 1 - a**2) / (1 - a))) for i in range(2, g): p[i] = V(((a - a**i) / (1 - a), a / (1 - a))) for i in range(1, g + 1): q[i] = V(((2 * a - a**i - a**(i + 1)) / (2 * (1 - a)), (a - a**(g - i + 2)) / (1 - a))) P = ConvexPolygons(field) s = Surface_list(field) T = [None] * (2 * g + 1) Tp = [None] * (2 * g + 1) from sage.matrix.constructor import Matrix m = Matrix([[1, 0], [0, -1]]) for i in range(1, g + 1): # T_i is (P_0,Q_i,Q_{i-1}) T[i] = s.add_polygon( P(edges=[q[i] - p[0], q[i - 1] - q[i], p[0] - q[i - 1]])) # T_{g+i} is (P_i,Q_{i-1},Q_{i}) T[g + i] = s.add_polygon( P(edges=[q[i - 1] - p[i], q[i] - q[i - 1], p[i] - q[i]])) # T'_i is (P'_0,Q'_{i-1},Q'_i) Tp[i] = s.add_polygon(m * s.polygon(T[i])) # T'_{g+i} is (P'_i,Q'_i, Q'_{i-1}) Tp[g + i] = s.add_polygon(m * s.polygon(T[g + i])) for i in range(1, g): s.change_edge_gluing(T[i], 0, T[i + 1], 2) s.change_edge_gluing(Tp[i], 2, Tp[i + 1], 0) for i in range(1, g + 1): s.change_edge_gluing(T[i], 1, T[g + i], 1) s.change_edge_gluing(Tp[i], 1, Tp[g + i], 1) #P 0 Q 0 is paired with P' 0 Q' 0, ... s.change_edge_gluing(T[1], 2, Tp[g], 2) s.change_edge_gluing(Tp[1], 0, T[g], 0) # P1Q1 is paired with P'_g Q_{g-1} s.change_edge_gluing(T[g + 1], 2, Tp[2 * g], 2) s.change_edge_gluing(Tp[g + 1], 0, T[2 * g], 0) # P1Q0 is paired with P_{g-1} Q_{g-1} s.change_edge_gluing(T[g + 1], 0, T[2 * g - 1], 2) s.change_edge_gluing(Tp[g + 1], 2, Tp[2 * g - 1], 0) # PgQg is paired with Q1P2 s.change_edge_gluing(T[2 * g], 2, T[g + 2], 0) s.change_edge_gluing(Tp[2 * g], 0, Tp[g + 2], 2) for i in range(2, g - 1): # PiQi is paired with Q'_i P'_{i+1} s.change_edge_gluing(T[g + i], 2, Tp[g + i + 1], 2) s.change_edge_gluing(Tp[g + i], 0, T[g + i + 1], 0) s.set_immutable() return TranslationSurface(s)