Exemplo n.º 1
0
    def __call__(self, hmult, vmult):
        r"""
        INPUT:

        - ``hmult`` -- multiplicities of the horizontal twists

        - ``vmult`` -- multiplicities of the vertical twists
        """
        if len(hmult) != self._num_hcyls or len(vmult) != self._num_vcyls:
            raise ValueError("invalid input lengths")

        E = self._E
        H = E * diagonal_matrix(vmult)
        V = E.transpose() * diagonal_matrix(hmult)

        if self._num_hcyls < self._num_vcyls:
            F = H * V
        else:
            F = V * H
        p = F.charpoly()
        assert F.nrows() == F.ncols() == min(
            [self._num_hcyls, self._num_vcyls])

        pf = max(p.roots(AA, False))
        mp = pf.minpoly()
        if mp.degree() == 1:
            K = QQ
            pf = QQ(pf)
        else:
            fwd, bck, q = do_polred(pf.minpoly())
            im_gen = fwd(pf)
            K = NumberField(q, 'a', embedding=im_gen)
            pf = bck(K.gen())

        # Compute widths of the cylinders via Perron-Frobenius
        if self._num_hcyls < self._num_vcyls:
            hcirc = (F - pf).right_kernel_matrix()
            assert hcirc.nrows() == 1
            assert hcirc.ncols() == self._num_hcyls
            hcirc = hcirc[0]
            assert all(x > 0 for x in hcirc)
            vcirc = V * hcirc
            c = 1
            d = pf
        else:
            vcirc = (F - pf).right_kernel_matrix()
            assert vcirc.nrows() == 1
            assert vcirc.ncols() == self._num_vcyls
            vcirc = vcirc[0]
            assert all(x > 0 for x in vcirc)
            hcirc = H * vcirc
            d = 1
            c = pf

        # Solve linear systems to get heights
        h = [hcirc[i] * hmult[i] / c for i in range(self._num_hcyls)]
        v = [vcirc[i] * vmult[i] / d for i in range(self._num_vcyls)]

        C = ConvexPolygons(K)
        P = []
        for i in range(self._o.nb_squares()):
            hi = h[self._hcycles[i]]
            vi = v[self._vcycles[i]]
            P.append(C(edges=[(vi, 0), (0, hi), (-vi, 0), (0, -hi)]))

        surface = Surface_list(base_ring=K)
        for p in P:
            surface.add_polygon(p)
        r = self._o.r_tuple()
        u = self._o.u_tuple()
        for i in range(self._o.nb_squares()):
            surface.set_edge_pairing(i, 1, r[i], 3)
            surface.set_edge_pairing(i, 0, u[i], 2)
        surface.set_immutable()
        return TranslationSurface(surface)