### Navigation

- index
- modules |
- next |
- previous |
- Modules »

# Morphisms of free modules

AUTHORS:
  - William Stein: initial version
  - Miguel Marco (2010-06-19): added eigenvalues, eigenvectors and minpoly functions

TESTS:

    sage: V = ZZ^2; f = V.hom([V.1,-2*V.0])
    sage: loads(dumps(f))
    Free module morphism defined by the matrix
    [ 0  1]
    [-2  0]
    Domain: Ambient free module of rank 2 over the principal ideal domain ...
    Codomain: Ambient free module of rank 2 over the principal ideal domain ...
    sage: loads(dumps(f)) == f
    True

class `sage.modules.free_module_morphism.``FreeModuleMorphism`(parent, A)

  Bases: `sage.modules.matrix_morphism.MatrixMorphism`

  INPUT:

  > - `parent` - a homspace in a (sub) category of free modules
  > - `A` - matrix

  EXAMPLES:

      sage: V = ZZ^3; W = span([[1,2,3],[-1,2,8]], ZZ)
      sage: phi = V.hom(matrix(ZZ,3,[1..9]))
      sage: type(phi)
      <class 'sage.modules.free_module_morphism.FreeModuleMorphism'>

  `change_ring`(R)

    Change the ring over which this morphism is defined. This changes the ring of the domain, codomain, and underlying matrix.

    EXAMPLES:

        sage: V0 = span([[0,0,1],[0,2,0]],ZZ); V1 = span([[1/2,0],[0,2]],ZZ); W = span([[1,0],[0,6]],ZZ)
        sage: h = V0.hom([-3*V1.0-3*V1.1, -3*V1.0-3*V1.1])
        sage: h.base_ring()
        Integer Ring
        sage: h
        Free module morphism defined by the matrix
        [-3 -3]
        [-3 -3]...
        sage: h.change_ring(QQ).base_ring()
        Rational Field
        sage: f = h.change_ring(QQ); f
        Vector space morphism represented by the matrix:
        [-3 -3]
        [-3 -3]
        Domain: Vector space of degree 3 and dimension 2 over Rational Field
        Basis matrix:
        [0 1 0]
        [0 0 1]
        Codomain: Vector space of degree 2 and dimension 2 over Rational Field
        Basis matrix:
        [1 0]
        [0 1]
        sage: f = h.change_ring(GF(7)); f
        Vector space morphism represented by the matrix:
        [4 4]
        [4 4]
        Domain: Vector space of degree 3 and dimension 2 over Finite Field of size 7
        Basis matrix:
        [0 1 0]
        [0 0 1]
        Codomain: Vector space of degree 2 and dimension 2 over Finite Field of size 7
        Basis matrix:
        [1 0]
        [0 1]

  `eigenvalues`(extend=True)

    Returns a list with the eigenvalues of the endomorphism of vector spaces.

    INPUT:

    - `extend` – boolean (default: True) decides if base field extensions should be considered or not.

    EXAMPLES:

    We compute the eigenvalues of an endomorphism of \(\QQ^3\):

        sage: V=QQ^3
        sage: H=V.endomorphism_ring()([[1,-1,0],[-1,1,1],[0,3,1]])
        sage: H.eigenvalues()
        [3, 1, -1]

    Note the effect of the `extend` option:

        sage: V=QQ^2
        sage: H=V.endomorphism_ring()([[0,-1],[1,0]])
        sage: H.eigenvalues()
        [-1*I, 1*I]
        sage: H.eigenvalues(extend=False)
        []

  `eigenvectors`(extend=True)

    Computes the subspace of eigenvectors of a given eigenvalue.

    INPUT:

    - `extend` – boolean (default: True) decides if base field extensions should be considered or not.

    OUTPUT:

    A sequence of tuples. Each tuple contains an eigenvalue, a sequence with a basis of the corresponding subspace of eigenvectors, and the algebraic multiplicity of the eigenvalue.

    EXAMPLES:

        sage: V=(QQ^4).subspace([[0,2,1,4],[1,2,5,0],[1,1,1,1]])
        sage: H=(V.Hom(V))(matrix(QQ, [[0,1,0],[-1,0,0],[0,0,3]]))
        sage: H.eigenvectors()
        [(3, [
        (0, 0, 1, -6/7)
        ], 1), (-1*I, [
        (1, 1*I, 0, -0.571428571428572? + 2.428571428571429?*I)
        ], 1), (1*I, [
        (1, -1*I, 0, -0.571428571428572? - 2.428571428571429?*I)
        ], 1)]
        sage: H.eigenvectors(extend=False)
        [(3, [
        (0, 0, 1, -6/7)
        ], 1)]
        sage: H1=(V.Hom(V))(matrix(QQ, [[2,1,0],[0,2,0],[0,0,3]]))
        sage: H1.eigenvectors()
        [(3, [
        (0, 0, 1, -6/7)
        ], 1), (2, [
        (0, 1, 0, 17/7)
        ], 2)]
        sage: H1.eigenvectors(extend=False)
        [(3, [
        (0, 0, 1, -6/7)
        ], 1), (2, [
        (0, 1, 0, 17/7)
        ], 2)]

  `inverse_image`(V)

    Given a submodule V of the codomain of self, return the inverse image of V under self, i.e., the biggest submodule of the domain of self that maps into V.

    EXAMPLES:

    We test computing inverse images over a field:

        sage: V = QQ^3; W = span([[1,2,3],[-1,2,5/3]], QQ)
        sage: phi = V.hom(matrix(QQ,3,[1..9]))
        sage: phi.rank()
        2
        sage: I = phi.inverse_image(W); I
        Vector space of degree 3 and dimension 2 over Rational Field
        Basis matrix:
        [   1    0    0]
        [   0    1 -1/2]
        sage: phi(I.0) in W
        True
        sage: phi(I.1) in W
        True
        sage: W = phi.image()
        sage: phi.inverse_image(W) == V
        True

    We test computing inverse images between two spaces embedded in different ambient spaces.:

        sage: V0 = span([[0,0,1],[0,2,0]],ZZ); V1 = span([[1/2,0],[0,2]],ZZ); W = span([[1,0],[0,6]],ZZ)
        sage: h = V0.hom([-3*V1.0-3*V1.1, -3*V1.0-3*V1.1])
        sage: h.inverse_image(W)
        Free module of degree 3 and rank 2 over Integer Ring
        Echelon basis matrix:
        [0 2 1]
        [0 0 2]
        sage: h(h.inverse_image(W)).is_submodule(W)
        True
        sage: h(h.inverse_image(W)).index_in(W)
        +Infinity
        sage: h(h.inverse_image(W))
        Free module of degree 2 and rank 1 over Integer Ring
        Echelon basis matrix:
        [ 3 12]

    We test computing inverse images over the integers:

        sage: V = QQ^3; W = V.span_of_basis([[2,2,3],[-1,2,5/3]], ZZ)
        sage: phi = W.hom([W.0, W.0-W.1])
        sage: Z = W.span([2*W.1]); Z
        Free module of degree 3 and rank 1 over Integer Ring
        Echelon basis matrix:
        [    2    -4 -10/3]
        sage: Y = phi.inverse_image(Z); Y
        Free module of degree 3 and rank 1 over Integer Ring
        Echelon basis matrix:
        [  6   0 8/3]
        sage: phi(Y) == Z
        True

  `lift`(x)

    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)

  `minimal_polynomial`(var='x')

    Computes the minimal polynomial.

    `minpoly()` and `minimal_polynomial()` are the same method.

    INPUT:

    - `var` - string (default: ‘x’) a variable name

    OUTPUT:

    polynomial in var - the minimal polynomial of the endomorphism.

    EXAMPLES:

    Compute the minimal polynomial, and check it.

        sage: V=GF(7)^3
        sage: H=V.Hom(V)([[0,1,2],[-1,0,3],[2,4,1]])
        sage: H
        Vector space morphism represented by the matrix:
        [0 1 2]
        [6 0 3]
        [2 4 1]
        Domain: Vector space of dimension 3 over Finite Field of size 7
        Codomain: Vector space of dimension 3 over Finite Field of size 7

        sage: H.minpoly()
        x^3 + 6*x^2 + 6*x + 1

        sage: H.minimal_polynomial()
        x^3 + 6*x^2 + 6*x + 1

        sage: H^3 + (H^2)*6 + H*6 + 1
        Vector space morphism represented by the matrix:
        [0 0 0]
        [0 0 0]
        [0 0 0]
        Domain: Vector space of dimension 3 over Finite Field of size 7
        Codomain: Vector space of dimension 3 over Finite Field of size 7

  `minpoly`(var='x')

    Computes the minimal polynomial.

    `minpoly()` and `minimal_polynomial()` are the same method.

    INPUT:

    - `var` - string (default: ‘x’) a variable name

    OUTPUT:

    polynomial in var - the minimal polynomial of the endomorphism.

    EXAMPLES:

    Compute the minimal polynomial, and check it.

        sage: V=GF(7)^3
        sage: H=V.Hom(V)([[0,1,2],[-1,0,3],[2,4,1]])
        sage: H
        Vector space morphism represented by the matrix:
        [0 1 2]
        [6 0 3]
        [2 4 1]
        Domain: Vector space of dimension 3 over Finite Field of size 7
        Codomain: Vector space of dimension 3 over Finite Field of size 7

        sage: H.minpoly()
        x^3 + 6*x^2 + 6*x + 1

        sage: H.minimal_polynomial()
        x^3 + 6*x^2 + 6*x + 1

        sage: H^3 + (H^2)*6 + H*6 + 1
        Vector space morphism represented by the matrix:
        [0 0 0]
        [0 0 0]
        [0 0 0]
        Domain: Vector space of dimension 3 over Finite Field of size 7
        Codomain: Vector space of dimension 3 over Finite Field of size 7

  `preimage_representative`(x)

    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)

`sage.modules.free_module_morphism.``is_FreeModuleMorphism`(x)

  EXAMPLES:

      sage: V = ZZ^2; f = V.hom([V.1,-2*V.0])
      sage: sage.modules.free_module_morphism.is_FreeModuleMorphism(f)
      True
      sage: sage.modules.free_module_morphism.is_FreeModuleMorphism(0)
      False

### Navigation

- index
- modules |
- next |
- previous |
- Modules »