Exemple #1
0
    def lift(self, x):
        r"""
        Given an element of the image, return an element of the codomain that maps onto it.

        Note that ``lift`` and ``preimage_representative`` are
        equivalent names for this method, with the latter suggesting
        that the return value is a coset representative of the domain
        modulo the kernel of the morphism.

        EXAMPLE::

            sage: X = QQ**2
            sage: V = X.span([[2, 0], [0, 8]], ZZ)
            sage: W = (QQ**1).span([[1/12]], ZZ)
            sage: f = V.hom([W([1/3]), W([1/2])], W)
            sage: f.lift([1/3])
            (8, -16)
            sage: f.lift([1/2])
            (12, -24)
            sage: f.lift([1/6])
            (4, -8)
            sage: f.lift([1/12])
            Traceback (most recent call last):
            ...
            ValueError: element is not in the image
            sage: f.lift([1/24])
            Traceback (most recent call last):
            ...
            TypeError: element (= [1/24]) is not in free module

        This works for vector spaces, too::

            sage: V = VectorSpace(GF(3), 2)
            sage: W = VectorSpace(GF(3), 3)
            sage: f = V.hom([W.1, W.1 - W.0])
            sage: f.lift(W.1)
            (1, 0)
            sage: f.lift(W.2)
            Traceback (most recent call last):
            ...
            ValueError: element is not in the image
            sage: w = W((17, -2, 0))
            sage: f(f.lift(w)) == w
            True

        This example illustrates the use of the ``preimage_representative``
        as an equivalent name for this method.  ::

            sage: V = ZZ^3
            sage: W = ZZ^2
            sage: w = vector(ZZ, [1,2])
            sage: f = V.hom([w, w, w], W)
            sage: f.preimage_representative(vector(ZZ, [10, 20]))
            (0, 0, 10)
        """
        from free_module_element import vector
        x = self.codomain()(x)
        A = self.matrix()
        R = self.base_ring()
        if R.is_field():
            try:
                C = A.solve_left(x)
            except ValueError:
                raise ValueError("element is not in the image")
        else:
            # see inverse_image for similar code but with comments
            if not hasattr(A, 'hermite_form'):
                raise NotImplementedError("base ring (%s) must have hermite_form algorithm in order to compute inverse image"%R)
            H, U = A.hermite_form(transformation=True,include_zero_rows=False)
            Y = H.solve_left(vector(self.codomain().coordinates(x)))
            C = Y*U
        try:
            t = self.domain().linear_combination_of_basis(C)
        except TypeError:
            raise ValueError("element is not in the image")
        assert self(t) == x
        return t
Exemple #2
0
    def lift(self, x):
        r"""
        Given an element of the image, return an element of the codomain that maps onto it.

        Note that ``lift`` and ``preimage_representative`` are
        equivalent names for this method, with the latter suggesting
        that the return value is a coset representative of the domain
        modulo the kernel of the morphism.

        EXAMPLE::

            sage: X = QQ**2
            sage: V = X.span([[2, 0], [0, 8]], ZZ)
            sage: W = (QQ**1).span([[1/12]], ZZ)
            sage: f = V.hom([W([1/3]), W([1/2])], W)
            sage: f.lift([1/3])
            (8, -16)
            sage: f.lift([1/2])
            (12, -24)
            sage: f.lift([1/6])
            (4, -8)
            sage: f.lift([1/12])
            Traceback (most recent call last):
            ...
            ValueError: element is not in the image
            sage: f.lift([1/24])
            Traceback (most recent call last):
            ...
            TypeError: element [1/24] is not in free module

        This works for vector spaces, too::

            sage: V = VectorSpace(GF(3), 2)
            sage: W = VectorSpace(GF(3), 3)
            sage: f = V.hom([W.1, W.1 - W.0])
            sage: f.lift(W.1)
            (1, 0)
            sage: f.lift(W.2)
            Traceback (most recent call last):
            ...
            ValueError: element is not in the image
            sage: w = W((17, -2, 0))
            sage: f(f.lift(w)) == w
            True

        This example illustrates the use of the ``preimage_representative``
        as an equivalent name for this method.  ::

            sage: V = ZZ^3
            sage: W = ZZ^2
            sage: w = vector(ZZ, [1,2])
            sage: f = V.hom([w, w, w], W)
            sage: f.preimage_representative(vector(ZZ, [10, 20]))
            (0, 0, 10)
        """
        from free_module_element import vector
        x = self.codomain()(x)
        A = self.matrix()
        R = self.base_ring()
        if R.is_field():
            try:
                C = A.solve_left(x)
            except ValueError:
                raise ValueError("element is not in the image")
        else:
            # see inverse_image for similar code but with comments
            if not hasattr(A, 'hermite_form'):
                raise NotImplementedError(
                    "base ring (%s) must have hermite_form algorithm in order to compute inverse image"
                    % R)
            H, U = A.hermite_form(transformation=True, include_zero_rows=False)
            Y = H.solve_left(vector(self.codomain().coordinates(x)))
            C = Y * U
        try:
            t = self.domain().linear_combination_of_basis(C)
        except TypeError:
            raise ValueError("element is not in the image")
        assert self(t) == x
        return t