Ejemplo n.º 1
0
 def __init__(self, cvs=None, z_center=1j, scale=5.0, bg=white):
     self.g_center = Mobius.cayley(z_center) * ~Mobius.cayley()
     if cvs is None:
         cvs = Canvas()
     cvs.append(Scale(scale))
     if bg is not None:
         cvs.fill(path.rect(-1, -1, 2, 2), [bg])
     self.cvs = cvs
Ejemplo n.º 2
0
    def _construct_short(cls, z0, z1):
        g = Mobius.get_translate(z0, z1)
        l, r = g.fixed()
        src, tgt = l, r

        theta0 = get_angle(src)
        theta1 = get_angle(tgt)
        r_cos = 1 / cos(0.5 * abs(theta0 - theta1))
        radius = tan(0.5 * abs(theta0 - theta1))
        z_center = r_cos * cmath.exp(1j * 0.5 * (theta0 + theta1))

        if radius < 0:
            radius = -radius

        theta0 = get_angle(z0 - z_center) % (2 * pi)
        theta1 = get_angle(z1 - z_center) % (2 * pi)
        theta2 = 0.5 * (theta0 + theta1)
        z2 = z_center + radius * cmath.exp(1j * theta2)
        meths = [path.arc, path.arcn]
        idx = 0
        if theta0 > theta1:
            idx = 1
        #print(theta1-theta0)
        if abs(theta1 - theta0) > pi:
            theta1 = theta1 - 2 * pi
            idx = 1 - idx

        gamma = CircleGeodesic(z_center, radius, theta0, theta1, meths[idx])
        assert abs(gamma.z0 - z0) < EPSILON, (gamma.z0, z0)
        assert abs(gamma.z1 - z1) < EPSILON, (gamma.z1, z1)

        return gamma
Ejemplo n.º 3
0
def main_poincare_1():

    for (l, m, n, maxsize) in [(5, 2, 4, 4000)]:

        # build the rotation group generators
        a, b = [g.todisc() for g in mktriangle(l, m, n)]

        cvs = Canvas()
        cvs.append(Scale(2.))
        disc = Disc(cvs)

        z_face = 0j
        z_vert = (a * b).inner_fixed()

        gamma = Geodesic.construct(z_vert, (~a)(z_vert))
        z_edge = gamma.z2  # midpoint
        g_face = gamma.get_refl()
        gamma = Geodesic.construct(z_face, z_vert)
        g_edge = gamma.get_refl()
        g_vert = Mobius.conjugate()

        gens = [g_face, g_edge, g_vert]
        gens = gens + [~g for g in gens]
        G = mulclose(gens, verbose=True, maxsize=maxsize)

        faces, edges, verts = [], [], []
        for g in G:
            faces.append(g(z_face))
            edges.append(g(z_edge))
            verts.append(g(z_vert))

        for g in G:
            disc.show_geodesic(g(z_face),
                               g(z_vert),
                               attrs=st_round + [grey.alpha(0.1)])
        for g in G:
            disc.show_geodesic(g(z_face), g(z_edge), attrs=st_round + [grey])
        for g in G:
            disc.show_geodesic(g(z_vert), g(z_edge), attrs=st_round)


#        for [cl, zs] in ([green, faces], [blue, edges], [red, verts]):
        for [cl, zs] in ([red, verts], ):
            for z in zs:
                disc.show_point(z, [cl])

        disc.fini()
        disc.save("poincare-rotation-%d%d%d" % (l, m, n))
Ejemplo n.º 4
0
def main_bring():
    global cvs

    gens = [Mobius(1, 1, 0, 1), Mobius(0, 1, -1, 0)]
    gens = [Mobius(1, 2, 0, 1), Mobius(1, 0, -2, 1)]
    gens = mktriangle(5, 2, 5)

    a, b = gens
    z1 = (a * b).inner_fixed()  # pentagon center
    gens = [g.todisc() for g in gens]  # --------------- todisc --------------

    I = Mobius()

    cvs = Canvas([Scale(5)])
    disc = Disc(cvs, z1)

    a, b = gens
    ab = a * b
    c = ab
    ci = ~c
    assert (ci * ci * a).order() == 5
    assert ab.order() == 5

    z0 = a.inner_fixed()
    z1 = c.inner_fixed()  # pentagon center
    z2 = b.inner_fixed()  # edge center
    z3 = b(z0)  # other end of an edge

    #G = mulclose(gens, maxsize=2000)
    #G = [Mobius(), a, b, a*b, b*a]
    G = [ab**idx for idx in range(5)]

    # cvs.paint([white]) # broken ?!?

    aspect = 16 / 9
    h = 2.2
    w = aspect * h
    #cvs.fill(path.rect(-0.5*w, -0.5*h, w, h), [white])

    p = path.circle(0, 0, 1)
    #cvs.fill(p, [grey])
    #cvs.clip(p)
    #cvs.stroke(p)

    #G = mulclose([a, b, ~a, ~b], g0=~disc.g_center, maxsize=2000)
    G = mulclose([a, b], maxsize=800)  # 8000 is good
    op = ~disc.g_center
    #G = [op * g for g in G]

    bring = [I]
    #disc.show_fixed(a)
    edges = []
    for conj in [I, c, c * c, c * c * c, c * c * c * c]:
        b1 = conj * b * ~conj
        a1 = conj * a * ~conj
        #disc.show_fixed(a1) # _vertices
        #disc.show_fixed(b1) # edge midpoints
        z = b1.inner_fixed()
        edges.append(z)
        tx0, tx1 = (a1 * a1 * b1)**3, (a1 * b1 * a1)**3
        #bring += [tx0, ~tx0, tx1, ~tx1]

    def shrink(pts, center=None, alpha=0.07):
        if center is None:
            center = sum(pts) / len(pts)
        pts = [conv(alpha, z, center) for z in pts]
        return pts

    star = []
    for i in range(5):
        g = a**i
        star.append(g(edges[0]))
    #star = shrink(star, z0)
    #disc.show_polygon(star, [green]+st_round, [green.alpha(0.5)])

    edges = shrink(edges, z1)
    star = shrink(star, z0)

    def get_translates(w):
        found = []
        for g in G:
            if not g.is_translate():
                continue
            for z in found:
                if abs(z - g(w)) < EPSILON:
                    break
            else:
                yield g
                z = g(w)
                found.append(z)

    def show_sigma():
        g = a * ci * ci * a
        src, tgt = g.fixed()
        for i in range(5):
            op = ci**i
            disc.show_geodesic(op(src), op(tgt), [orange.alpha(0.4)])
            break

        #print(src)
        src = disc.g_center(src)
        #disc.show_point(src)
        x, y = src.real, src.imag
        #cvs.stroke(path.circle(x, y, 0.1))
        z = src * 1j
        dx, dy = 0.2 * z.real, 0.2 * z.imag
        cvs.text(x + 0.2, y - 0.1, r"$\sigma$", [Scale(0.5)] + st_center)

        r = 1.12
        cvs.stroke(path.line(x, y, r * x, r * y), [orange.alpha(0.4)])
        x, y = 1.1 * x, 1.1 * y
        st = [deco.earrow(size=0.1)] + [0.7 * thin]
        cvs.stroke(path.line(x, y, x + dx, y + dy), st)
        cvs.stroke(path.line(x, y, x - dx, y - dy), st)

    def show_faces(min_lw=0.00):

        for g in get_translates(z1):
            z = g(z1)
            lw = 4. / disc.d_poincare(z)
            if lw < min_lw:
                break
            pts = [g(v) for v in edges]
            disc.show_polygon(pts, [lw * thin, green] + st_round,
                              [green.alpha(0.3)])

        #disc.show_point(z0)

        for g in get_translates(z0):
            z = g(z0)
            lw = 4. / disc.d_poincare(z)
            if lw < min_lw:
                break
            pts = [g(v) for v in star]
            disc.show_polygon(pts, [lw * thin, blue] + st_round,
                              [blue.alpha(0.3)])

    #bring = [I]
    #G0 = mulclose([a, b], maxsize=20)
    #bring += [g*tx0*~g for g in G0]
    #bring += [g*tx1*~g for g in G0]

    #for op in bring[1:]:
    #    #disc.show_fixed(op)
    #    src, tgt = (op).fixed()
    #    disc.show_geodesic(src, tgt, [green.alpha(0.5)])

    #bring = [I, tx0*~tx1*tx0]
    #bring = mulclose([tx0, tx1, ~tx0, ~tx1], maxsize=20)
    #disc.show_fixed(bring[0])
    #bring = mulclose(bring, maxsize=200)

    def show_bring():
        tiles = [
            (
                1,
                I,
            ),
            (
                2,
                (c**3) * a,
            ),
            (
                3,
                (c**2) * a,
            ),
            (
                4,
                c * a,
            ),
            (
                5,
                a,
            ),
            (
                6,
                (c**4) * a,
            ),
            (
                7,
                a**2,
            ),
            (
                8,
                a**3,
            ),
            (
                9,
                ci * a**2,
            ),
            (
                10,
                ci * a**3,
            ),
            (
                11,
                ci**2 * a**2,
            ),
            (7, ci**2 * a**3),
            (
                8,
                ci**3 * a**2,
            ),
            (9, ci**3 * a**3),
            (
                10,
                ci**4 * a**2,
            ),
            (11, ci**4 * a**3),
        ]
        #g = ci*a**2
        #h = ci**3*a**3
        #disc.show_fixed(h*~g)
        #bring = [I, h*~g]
        g = a**3 * b * a**-3
        a1 = g * a * ~g
        #disc.show_fixed(a1*a1)
        #assert a1.order() == 5, a1.order()
        tiles.append((11, a1**2 * a**3))
        tiles.append((9, a1**4 * a**3))

        for (count, g) in tiles:
            #if count == 5:
            #    g = (tx0**-3)*g
            for h in bring:
                g2 = disc.g_center * h * g
                z = g2(z1)
                ds = 1. / d_poincare(z)**0.7
                if ds > 0.05:
                    cvs.text(z.real, z.imag, str(count),
                             [Scale(ds)] + st_center)
                #break

    #show_sigma()
    #show_faces()
    show_bring()

    disc.show_tiles(G)

    p = path.circle(0, 0, 1)
    cvs.clip(p)
    cvs.stroke(p, [1.0 * thin])

    #save("hyperbolic-55")
    #save("fold-hyperbolic-55")
    save("brings-curve")

    print("OK")
    print()
Ejemplo n.º 5
0
def render_group(l,
                 m,
                 n,
                 words=[],
                 rels=[],
                 labels={},
                 name="output",
                 maxsize=1000):

    # build the rotation group generators
    a, b = [g.todisc() for g in mktriangle(l, m, n)]
    assert (a.order()) == 10  # SL(2) not PSL(2)
    assert (b.order()) == 4  # SL(2) not PSL(2)
    c = (~b) * (~a)

    cvs = Canvas()
    cvs.append(Scale(4.))
    disc = Disc(cvs)

    z_face = 0j
    z_vert = (a * b).inner_fixed()

    gamma = Geodesic.construct(z_vert, (~a)(z_vert))
    z_edge = gamma.z2  # midpoint
    #z_tile = (1/3)*(z_face + z_edge + z_vert)
    z_tile = (1 / 2) * (z_face + z_vert)
    g_face = gamma.get_refl()
    gamma = Geodesic.construct(z_face, z_vert)
    g_edge = gamma.get_refl()
    g_vert = Mobius.conjugate()

    gens = [g_vert, ~g_vert, g_edge, ~g_edge, g_face, ~g_face]
    G = mulclose(gens, verbose=True, maxsize=maxsize)

    faces, edges, verts = [], [], []
    for g in G:
        faces.append(g(z_face))
        edges.append(g(z_edge))
        verts.append(g(z_vert))

    #for g in G:
    #    disc.show_geodesic(g(z_face), g(z_vert), attrs=st_round+[grey.alpha(0.1)])
    for g in G:
        disc.show_geodesic(g(z_face), g(z_edge), attrs=st_round + [grey])
    for g in G:
        disc.show_geodesic(g(z_vert), g(z_edge), attrs=st_round)

#    for [cl, zs] in ([green, faces], [blue, edges], [red, verts]):
    for [cl, zs] in ([red, verts], ):
        for z in zs:
            disc.show_point(z, fill_attrs=[white], stroke_attrs=[black])

    # ------------------------------------------------------

    I = Mobius()
    gens = [a, ~a, b, ~b, c, ~c]

    def get(word):
        g = reduce(mul, [gens[i] for i in word], I)
        return g

    for word in words:
        g = get(word)
        disc.show_point(g(z_tile), [blue.alpha(0.5)])

    scale = 0.4
    if labels:
        for (word, label) in labels.items():
            g = reduce(mul, [gens[w] for w in reversed(word)], I)
            disc.show_label(g(z_tile), label, scale)

    else:
        for (g, label) in [
            (I, r"$\star$"),
            (a, r"$a$"),
            (b, r"$b$"),
            (c, r"$c$"),
                #(c**2, r"$c^2$"),
                #(c**3, r"$c^3$"),
        ]:
            disc.show_label(g(z_tile), label, scale)

    for rel in rels:
        g = get(reversed(rel))
        disc.show_label(g(z_tile), "I", scale)

    disc.fini()
    disc.save(name)
Ejemplo n.º 6
0
def main_bring():
    # build the rotation group generators
    a, b = [g.todisc() for g in mktriangle(5, 2, 5)]

    disc = Disc()

    z_face = 0j
    z_vert = (a * b).inner_fixed()

    gamma = Geodesic.construct(z_vert, (~a)(z_vert))
    z_edge = gamma.z2  # midpoint
    g_face = gamma.get_refl()
    gamma = Geodesic.construct(z_face, z_vert)
    g_edge = gamma.get_refl()
    g_vert = Mobius.conjugate()

    gens = [g_face, g_edge, g_vert]
    gens = gens + [~g for g in gens]
    G = mulclose(gens, verbose=True, maxsize=8000)  # 8000 is enough

    faces, edges, verts = [], [], []
    for g in G:
        #disc.show_geodesic(g(z_face), g(z_vert), attrs=[grey])
        #disc.show_geodesic(g(z_face), g(z_edge), attrs=[grey])
        faces.append(g(z_face))
        edges.append(g(z_edge))
        verts.append(g(z_vert))

    for g in G:
        disc.show_geodesic(g(z_vert), g(z_edge), attrs=st_round)


#        break

#disc.show_polygon([z_face, z_edge, z_vert], st_fill=[grey])
#disc.show_point(z_vert, radius=0.1)
#disc.show_point((~a)(z_vert), radius=0.1)
#disc.show_point(z_edge, radius=0.1)

#    z1, z2 = z_vert, a(z_vert)
#    faces.append(0.j)
#    for i in range(5):
#        disc.show_geodesic(z1, z2)
#        gamma = Geodesic.construct(z1, z2)
#        disc.show_geodesic(0, z1)
#        disc.show_geodesic(0, gamma.z2)
#        edges.append(gamma.z2)
#        verts.append(gamma.z0)
#        #g = gamma.get_refl()
#        #disc.show_point(g(0))
#        z1, z2 = z2, a(z2)

    for z in edges:
        disc.show_qubit(z)

    #for [cl, zs] in ([green, faces], [blue, edges], [red, verts]):
    #    for z in zs:
    #        disc.show_point(z, [cl])

    I = Mobius()
    z = 0.j
    pts0 = []
    for (g, label) in [
        (I, "1"),
        (b, "6"),
        (a * b, "2"),
        (a * a * b, "3"),
        (a * a * a * b, "4"),
        (a * a * a * a * b, "5"),
        (b * a * b, "8"),
        (a * b * a * b, "10"),
        (a * a * b * a * b, "7"),
        (a * a * a * b * a * b, "9"),
        (a * a * a * a * b * a * b, "11"),
        (b * a * b * a * b, "7"),
        (a * b * a * b * a * b, "9"),
        (a * a * b * a * b * a * b, "11"),
        (a * a * a * b * a * b * a * b, "8"),
        (a * a * a * a * b * a * b * a * b, "10"),
        (a * b * a * a * b, "5"),
        (a * a * b * a * a * b, "6"),
        (a * a * a * b * a * a * b, "2"),
        (a * a * a * a * b * a * a * b, "3"),
        (a * a * a * a * a * b * a * a * b, "4"),
        (b * a * a * a * b, "3"),
        (a * b * a * a * a * b, "4"),
        (a * a * b * a * a * a * b, "5"),
        (a * a * a * b * a * a * a * b, "6"),
        (a * a * a * a * b * a * a * a * b, "2"),
        (b * a * a * a * a * b * a * b * a * b, "7"),
        (a * b * a * a * a * a * b * a * b * a * b, "9"),
        (a * a * b * a * a * a * a * b * a * b * a * b, "11"),
        (a * a * a * b * a * a * a * a * b * a * b * a * b, "8"),
        (a * a * a * a * b * a * a * a * a * b * a * b * a * b, "10"),
        (b * a * a * a * a * b * a * b, "12"),
        (a * b * a * a * a * a * b * a * b, "12"),
        (a * a * b * a * a * a * a * b * a * b, "12"),
        (a * a * a * b * a * a * a * a * b * a * b, "12"),
        (a * a * a * a * b * a * a * a * a * b * a * b, "12"),
        (b * a * b * a * a * a * a * b, "12"),
        (a * b * a * b * a * a * a * a * b, "12"),
        (a * a * b * a * b * a * a * a * a * b, "12"),
        (a * a * a * b * a * b * a * a * a * a * b, "12"),
        (a * a * a * a * b * a * b * a * a * a * a * b, "12"),
        (b * a * a * b * a * b, "10"),
        (a * b * a * a * b * a * b, "7"),
        (a * a * b * a * a * b * a * b, "9"),
        (a * a * a * b * a * a * b * a * b, "11"),
        (a * a * a * a * b * a * a * b * a * b, "8"),
    ]:
        z1 = g(z)
        z1 = 0.98 * z1
        disc.show_label(z1, label)
        #pts0.append(z1)
        #disc.show_point(z1, [red], radius=0.02)

    disc.fini()
    disc.save("brings-curve")
Ejemplo n.º 7
0
 def get_refl(self):
     z0, z1, z2 = self.z0, self.z1, self.z2
     g = Mobius.send(z0, z1, z2, -1, 0., 1.)
     C = Mobius(1, 0, 0, 1, True)  # conjugate
     return (~g) * C * g