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)