Пример #1
0
    def induced_out_partition(self, trans, ieq):
        r"""
        Returns the output partition obtained as the induction of the given
        transformation on the domain given by an inequality.

        Note: the output partition corresponds to the arrival partition in
        the domain, not the initial one.

        INPUT:

        - ``trans`` -- a function: polyhedron -> polyhedron
        - ``ieq`` -- list, an inequality. An entry equal to "[-1,7,3,4]"
          represents the inequality 7x_1+3x_2+4x_3>= 1.

        OUTPUT:

            dict of polyhedron partitions with keys giving the return time

        EXAMPLES::

            sage: from slabbe import PolyhedronPartition, rotation_mod
            sage: h = 1/3
            sage: p = Polyhedron([(0,h),(0,1),(h,1)])
            sage: q = Polyhedron([(0,0), (0,h), (h,1), (h,0)])
            sage: r = Polyhedron([(h,1), (1,1), (1,h), (h,0)])
            sage: s = Polyhedron([(h,0), (1,0), (1,h)])
            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: u = rotation_mod(0, 1/3, 1, QQ)
            sage: ieq = [h, -1, 0]   # x0 <= h
            sage: P.induced_out_partition(u, ieq)
            {3: Polyhedron partition of 4 atoms with 4 letters}

        ::

            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: ieq2 = [1/2, -1, 0]   # x0 <= 1/2
            sage: d = P.induced_out_partition(u, ieq2)
            sage: d
            {1: Polyhedron partition of 2 atoms with 2 letters,
             2: Polyhedron partition of 3 atoms with 3 letters,
             3: Polyhedron partition of 4 atoms with 4 letters}
            sage: Q = PolyhedronPartition(d[1].atoms()+d[2].atoms()+d[3].atoms())
            sage: Q.is_pairwise_disjoint()
            True

        ::

            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: ieq3 = [-1/2, 1, 0]   # x0 >= 1/2
            sage: P.induced_out_partition(u, ieq3)
            {2: Polyhedron partition of 3 atoms with 3 letters,
             3: Polyhedron partition of 4 atoms with 4 letters}

        It is an error if the induced region is empty::

            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: ieq4 = [-1/2, -1, 0]   # x0 <= -1/2
            sage: P.induced_out_partition(u, ieq4)
            Traceback (most recent call last):
            ...
            ValueError: Inequality An inequality (-2, 0) x - 1 >= 0 does
            not intersect P (=Polyhedron partition of 4 atoms with 4
            letters)

        The whole domain::

            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: ieq5 = [1/2, 1, 0]   # x0 >= -1/2
            sage: P.induced_out_partition(u, ieq5)
            {1: Polyhedron partition of 4 atoms with 4 letters}

        An irrational rotation::

            sage: z = polygen(QQ, 'z') #z = QQ['z'].0 # same as
            sage: K = NumberField(z**2-z-1, 'phi', embedding=RR(1.6))
            sage: phi = K.gen()
            sage: h = 1/phi^2
            sage: p = Polyhedron([(0,h),(0,1),(h,1)])
            sage: q = Polyhedron([(0,0), (0,h), (h,1), (h,0)])
            sage: r = Polyhedron([(h,1), (1,1), (1,h), (h,0)])
            sage: s = Polyhedron([(h,0), (1,0), (1,h)])
            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s}, base_ring=K)
            sage: u = rotation_mod(0, 1/phi, 1, K)
            sage: ieq = [phi^-4, -1, 0]   # x0 <= phi^-4
            sage: d = P.induced_out_partition(u, ieq)
            sage: d
            {5: Polyhedron partition of 6 atoms with 6 letters,
             8: Polyhedron partition of 9 atoms with 9 letters}
        """
        # good side of the hyperplane
        half = Polyhedron(ieqs=[ieq])
        half_part = PolyhedronPartition([half])
        # the other side of the hyperplane
        other_half = Polyhedron(ieqs=[[-a for a in ieq]])
        other_half_part = PolyhedronPartition([other_half])
        # initial refinement
        P = self.refinement(half_part)
        if len(P) == 0:
            raise ValueError("Inequality {} does not intersect P "
                    "(={})".format(half.inequalities()[0], self))
        level = 1
        ans = {}
        P = P.apply_transformation(trans)
        while len(P):
            P_returned = P.refinement(half_part)
            if P_returned:
                ans[level] = P_returned
            # for what is remaining we do:
            P = P.refinement(other_half_part)
            P = P.refinement(self)
            P = P.apply_transformation(trans)
            level += 1
        return ans