# Finite dimensional modules with basis#

class sage.categories.finite_dimensional_modules_with_basis.FiniteDimensionalModulesWithBasis(base_category)#

The category of finite dimensional modules with a distinguished basis

EXAMPLES:

sage: C = FiniteDimensionalModulesWithBasis(ZZ); C
Category of finite dimensional modules with basis over Integer Ring
sage: sorted(C.super_categories(), key=str)
[Category of finite dimensional modules over Integer Ring,
Category of modules with basis over Integer Ring]
sage: C is Modules(ZZ).WithBasis().FiniteDimensional()
True

class ElementMethods#

Bases: object

dense_coefficient_list(order=None)#

Return a list of all coefficients of self.

By default, this list is ordered in the same way as the indexing set of the basis of the parent of self.

INPUT:

• order – (optional) an ordering of the basis indexing set

EXAMPLES:

sage: v = vector([0, -1, -3])                                           # optional - sage.modules
sage: v.dense_coefficient_list()                                        # optional - sage.modules
[0, -1, -3]
sage: v.dense_coefficient_list([2,1,0])                                 # optional - sage.modules
[-3, -1, 0]
sage: sorted(v.coefficients())                                          # optional - sage.modules
[-3, -1]

class MorphismMethods#

Bases: object

image()#

Return the image of self as a submodule of the codomain.

EXAMPLES:

sage: SGA = SymmetricGroupAlgebra(QQ, 3)                                # optional - sage.groups sage.modules
sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA)        # optional - sage.groups sage.modules
sage: f.image()                                                         # optional - sage.groups sage.modules
Free module generated by {0, 1, 2} over Rational Field

image_basis()#

Return a basis for the image of self in echelon form.

EXAMPLES:

sage: SGA = SymmetricGroupAlgebra(QQ, 3)                                # optional - sage.groups sage.modules
sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA)        # optional - sage.groups sage.modules
sage: f.image_basis()                                                   # optional - sage.groups sage.modules
([1, 2, 3], [2, 3, 1], [3, 1, 2])

kernel()#

Return the kernel of self as a submodule of the domain.

EXAMPLES:

sage: SGA = SymmetricGroupAlgebra(QQ, 3)                                # optional - sage.groups sage.modules
sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA)        # optional - sage.groups sage.modules
sage: K = f.kernel()                                                    # optional - sage.groups sage.modules
sage: K                                                                 # optional - sage.groups sage.modules
Free module generated by {0, 1, 2} over Rational Field
sage: K.ambient()                                                       # optional - sage.groups sage.modules
Symmetric group algebra of order 3 over Rational Field

kernel_basis()#

Return a basis of the kernel of self in echelon form.

EXAMPLES:

sage: SGA = SymmetricGroupAlgebra(QQ, 3)                                # optional - sage.groups sage.modules
sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA)        # optional - sage.groups sage.modules
sage: f.kernel_basis()                                                  # optional - sage.groups sage.modules
([1, 2, 3] - [3, 2, 1], [1, 3, 2] - [3, 2, 1], [2, 1, 3] - [3, 2, 1])

matrix(base_ring=None, side='left')#

Return the matrix of this morphism in the distinguished bases of the domain and codomain.

INPUT:

• base_ring – a ring (default: None, meaning the base ring of the codomain)

• side – “left” or “right” (default: “left”)

If side is “left”, this morphism is considered as acting on the left; i.e. each column of the matrix represents the image of an element of the basis of the domain.

The order of the rows and columns matches with the order in which the bases are enumerated.

Modules.WithBasis.ParentMethods.module_morphism()

EXAMPLES:

sage: X = CombinatorialFreeModule(ZZ, [1,2]); x = X.basis()             # optional - sage.modules
sage: Y = CombinatorialFreeModule(ZZ, [3,4]); y = Y.basis()             # optional - sage.modules
sage: phi = X.module_morphism(on_basis={1: y[3] + 3*y[4],               # optional - sage.modules
....:                                   2: 2*y[3] + 5*y[4]}.__getitem__,
....:                         codomain=Y)
sage: phi.matrix()                                                      # optional - sage.modules
[1 2]
[3 5]
sage: phi.matrix(side="right")                                          # optional - sage.modules
[1 3]
[2 5]

sage: phi.matrix().parent()                                             # optional - sage.modules
Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
sage: phi.matrix(QQ).parent()                                           # optional - sage.modules
Full MatrixSpace of 2 by 2 dense matrices over Rational Field


The resulting matrix is immutable:

sage: phi.matrix().is_mutable()                                         # optional - sage.modules
False


The zero morphism has a zero matrix:

sage: Hom(X, Y).zero().matrix()                                         # optional - sage.modules
[0 0]
[0 0]


Todo

Add support for morphisms where the codomain has a different base ring than the domain:

sage: Y = CombinatorialFreeModule(QQ, [3,4]); y = Y.basis()         # optional - sage.modules
sage: phi = X.module_morphism(on_basis={1: y[3] + 3*y[4],           # optional - sage.modules
....:                                   2: 2*y[3] + 5/2*y[4]}.__getitem__,
....:                         codomain=Y)
sage: phi.matrix().parent()          # todo: not implemented        # optional - sage.modules
Full MatrixSpace of 2 by 2 dense matrices over Rational Field


This currently does not work because, in this case, the morphism is just in the category of commutative additive groups (i.e. the intersection of the categories of modules over $$\ZZ$$ and over $$\QQ$$):

sage: phi.parent().homset_category()                                # optional - sage.modules
sage: phi.parent().homset_category() # todo: not implemented        # optional - sage.modules
Category of finite dimensional modules with basis over Integer Ring

class ParentMethods#

Bases: object

annihilator(S, action=<built-in function mul>, side='right', category=None)#

Return the annihilator of a finite set.

INPUT:

• S – a finite set

• action – a function (default: operator.mul)

• side – ‘left’ or ‘right’ (default: ‘right’)

• category – a category

Assumptions:

• action takes elements of self as first argument and elements of S as second argument;

• The codomain is any vector space, and action is linear on its first argument; typically it is bilinear;

• If side is ‘left’, this is reversed.

OUTPUT:

The subspace of the elements $$x$$ of self such that action(x,s) = 0 for all $$s\in S$$. If side is ‘left’ replace the above equation by action(s,x) = 0.

If self is a ring, action an action of self on a module $$M$$ and $$S$$ is a subset of $$M$$, we recover the Wikipedia article Annihilator_%28ring_theory%29. Similarly this can be used to compute torsion or orthogonals.

annihilator_basis() for lots of examples.

EXAMPLES:

sage: F = FiniteDimensionalAlgebrasWithBasis(QQ).example(); F           # optional - sage.modules
An example of a finite dimensional algebra with basis:
the path algebra of the Kronecker quiver
(containing the arrows a:x->y and b:x->y) over Rational Field
sage: x, y, a, b = F.basis()                                            # optional - sage.modules
sage: A = F.annihilator([a + 3*b + 2*y]); A                             # optional - sage.modules
Free module generated by {0} over Rational Field
sage: [b.lift() for b in A.basis()]                                     # optional - sage.modules
[-1/2*a - 3/2*b + x]


The category can be used to specify other properties of this subspace, like that this is a subalgebra:

sage: center = F.annihilator(F.basis(), F.bracket,                      # optional - sage.modules
....:                        category=Algebras(QQ).Subobjects())
sage: (e,) = center.basis()                                             # optional - sage.modules
sage: e.lift()                                                          # optional - sage.modules
x + y
sage: e * e == e                                                        # optional - sage.modules
True


Taking annihilator is order reversing for inclusion:

sage: A   = F.annihilator([]);    A  .rename("A")                       # optional - sage.modules
sage: Ax  = F.annihilator([x]);   Ax .rename("Ax")                      # optional - sage.modules
sage: Ay  = F.annihilator([y]);   Ay .rename("Ay")                      # optional - sage.modules
sage: Axy = F.annihilator([x,y]); Axy.rename("Axy")                     # optional - sage.modules
sage: P = Poset(([A, Ax, Ay, Axy], attrcall("is_submodule")))           # optional - sage.combinat sage.graphs sage.modules
sage: sorted(P.cover_relations(), key=str)                              # optional - sage.combinat sage.graphs sage.modules
[[Ax, A], [Axy, Ax], [Axy, Ay], [Ay, A]]

annihilator_basis(S, action=<built-in function mul>, side='right')#

Return a basis of the annihilator of a finite set of elements.

INPUT:

• S – a finite set of objects

• action – a function (default: operator.mul)

• side – ‘left’ or ‘right’ (default: ‘right’): on which side of self the elements of $$S$$ acts.

See annihilator() for the assumptions and definition of the annihilator.

EXAMPLES:

By default, the action is the standard $$*$$ operation. So our first example is about an algebra:

sage: F = FiniteDimensionalAlgebrasWithBasis(QQ).example(); F
An example of a finite dimensional algebra with basis:
the path algebra of the Kronecker quiver
(containing the arrows a:x->y and b:x->y) over Rational Field
sage: x,y,a,b = F.basis()


In this algebra, multiplication on the right by $$x$$ annihilates all basis elements but $$x$$:

sage: x*x, y*x, a*x, b*x
(x, 0, 0, 0)


So the annihilator is the subspace spanned by $$y$$, $$a$$, and $$b$$:

sage: F.annihilator_basis([x])
(y, a, b)


The same holds for $$a$$ and $$b$$:

sage: x*a, y*a, a*a, b*a
(a, 0, 0, 0)
sage: F.annihilator_basis([a])
(y, a, b)


On the other hand, $$y$$ annihilates only $$x$$:

sage: F.annihilator_basis([y])
(x,)


Here is a non trivial annihilator:

sage: F.annihilator_basis([a + 3*b + 2*y])
(-1/2*a - 3/2*b + x,)


Let’s check it:

sage: (-1/2*a - 3/2*b + x) * (a + 3*b + 2*y)
0


Doing the same calculations on the left exchanges the roles of $$x$$ and $$y$$:

sage: F.annihilator_basis([y], side="left")
(x, a, b)
sage: F.annihilator_basis([a], side="left")
(x, a, b)
sage: F.annihilator_basis([b], side="left")
(x, a, b)
sage: F.annihilator_basis([x], side="left")
(y,)
sage: F.annihilator_basis([a+3*b+2*x], side="left")
(-1/2*a - 3/2*b + y,)


By specifying an inner product, this method can be used to compute the orthogonal of a subspace:

sage: x,y,a,b = F.basis()
sage: def scalar(u,v):
....:     return vector([sum(u[i]*v[i] for i in F.basis().keys())])
sage: F.annihilator_basis([x+y, a+b], scalar)
(x - y, a - b)


By specifying the standard Lie bracket as action, one can compute the commutator of a subspace of $$F$$:

sage: F.annihilator_basis([a+b], action=F.bracket)
(x + y, a, b)


In particular one can compute a basis of the center of the algebra. In our example, it is reduced to the identity:

sage: F.annihilator_basis(F.algebra_generators(), action=F.bracket)
(x + y,)

echelon_form(elements, row_reduced=False, order=None)#

Return a basis in echelon form of the subspace spanned by a finite set of elements.

INPUT:

• elements – a list or finite iterable of elements of self

• row_reduced – (default: False) whether to compute the basis for the row reduced echelon form

• order – (optional) either something that can be converted into a tuple or a key function

OUTPUT:

A list of elements of self whose expressions as vectors form a matrix in echelon form. If base_ring is specified, then the calculation is achieved in this base ring.

EXAMPLES:

sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x")             # optional - sage.modules
sage: x = X.basis()                                                     # optional - sage.modules
sage: V = X.echelon_form([x[0]-x[1], x[0]-x[2], x[1]-x[2]]); V          # optional - sage.modules
[x[0] - x[2], x[1] - x[2]]
sage: matrix(list(map(vector, V)))                                      # optional - sage.modules
[ 1  0 -1]
[ 0  1 -1]

sage: F = CombinatorialFreeModule(ZZ, [1,2,3,4])                        # optional - sage.modules
sage: B = F.basis()                                                     # optional - sage.modules
sage: elements = [B[1]-17*B[2]+6*B[3], B[1]-17*B[2]+B[4]]               # optional - sage.modules
sage: F.echelon_form(elements)                                          # optional - sage.modules
[B[1] - 17*B[2] + B[4], 6*B[3] - B[4]]

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])                    # optional - sage.modules
sage: a,b,c = F.basis()                                                 # optional - sage.modules
sage: F.echelon_form([8*a+b+10*c, -3*a+b-c, a-b-c])                     # optional - sage.modules
[B['a'] + B['c'], B['b'] + 2*B['c']]

sage: R.<x,y> = QQ[]
sage: C = CombinatorialFreeModule(R, range(3), prefix='x')              # optional - sage.modules
sage: x = C.basis()                                                     # optional - sage.modules
sage: C.echelon_form([x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]])       # optional - sage.modules
[x[0] - x[2], x[1] - x[2]]

sage: M = MatrixSpace(QQ, 3, 3)                                         # optional - sage.modules
sage: A = M([[0, 0, 2], [0, 0, 0], [0, 0, 0]])                          # optional - sage.modules
sage: M.echelon_form([A, A])                                            # optional - sage.modules
[
[0 0 1]
[0 0 0]
[0 0 0]
]

from_vector(vector, order=None, coerce=True)#

Build an element of self from a vector.

EXAMPLES:

sage: p_mult = matrix([[0,0,0], [0,0,-1], [0,0,0]])                     # optional - sage.modules
sage: q_mult = matrix([[0,0,1], [0,0,0], [0,0,0]])                      # optional - sage.modules
sage: A = algebras.FiniteDimensional(                                   # optional - sage.combinat sage.modules
....:         QQ, [p_mult, q_mult, matrix(QQ, 3, 3)], 'p,q,z')
sage: A.from_vector(vector([1,0,2]))                                    # optional - sage.combinat sage.modules
p + 2*z

gens()#

Return the generators of self.

OUTPUT:

A tuple containing the basis elements of self.

EXAMPLES:

sage: F = CombinatorialFreeModule(ZZ, ['a', 'b', 'c'])                  # optional - sage.modules
sage: F.gens()                                                          # optional - sage.modules
(B['a'], B['b'], B['c'])

invariant_module(S, action=<built-in function mul>, action_on_basis=None, side='left', **kwargs)#

Return the submodule of self invariant under the action of S.

For a semigroup $$S$$ acting on a module $$M$$, the invariant submodule is given by

$M^S = \{m \in M : s \cdot m = m,\, \forall s \in S\}.$

INPUT:

• S – a finitely-generated semigroup

• action – a function (default: operator.mul)

• side'left' or 'right' (default: 'right'); which side of self the elements of S acts

• action_on_basis – (optional) define the action of S on the basis of self

OUTPUT:

EXAMPLES:

We build the invariant module of the permutation representation of the symmetric group:

sage: G = SymmetricGroup(3); G.rename('S3')                             # optional - sage.groups sage.modules
sage: M = FreeModule(ZZ, [1,2,3], prefix='M'); M.rename('M')            # optional - sage.groups sage.modules
sage: action = lambda g, x: M.term(g(x))
sage: I = M.invariant_module(G, action_on_basis=action); I              # optional - sage.groups sage.modules
(S3)-invariant submodule of M
sage: I.basis()                                                         # optional - sage.groups sage.modules
Finite family {0: B[0]}
sage: [I.lift(b) for b in I.basis()]                                    # optional - sage.groups sage.modules
[M[1] + M[2] + M[3]]

sage: G.rename(); M.rename()  # reset the names                         # optional - sage.groups sage.modules


We can construct the invariant module of any module that has an action of S. In this example, we consider the dihedral group $$G = D_4$$ and the subgroup $$H < G$$ of all rotations. We construct the $$H$$-invariant module of the group algebra $$\QQ[G]$$:

sage: G = groups.permutation.Dihedral(4)                                # optional - sage.groups
sage: H = G.subgroup(G.gen(0))                                          # optional - sage.groups
sage: H                                                                 # optional - sage.groups
Subgroup generated by [(1,2,3,4)]
of (Dihedral group of order 8 as a permutation group)
sage: H.cardinality()                                                   # optional - sage.groups
4
sage: A = G.algebra(QQ)                                                 # optional - sage.groups sage.modules
sage: I = A.invariant_module(H)                                         # optional - sage.groups sage.modules
sage: [I.lift(b) for b in I.basis()]                                    # optional - sage.groups sage.modules
[() + (1,2,3,4) + (1,3)(2,4) + (1,4,3,2),
(2,4) + (1,2)(3,4) + (1,3) + (1,4)(2,3)]
sage: all(h * I.lift(b) == I.lift(b)                                    # optional - sage.groups sage.modules
....:     for b in I.basis() for h in H)
True

twisted_invariant_module(G, chi, action=<built-in function mul>, action_on_basis=None, side='left', **kwargs)#

Create the isotypic component of the action of G on self with irreducible character given by chi.

INPUT:

• G – a finitely-generated group

• chi – a list/tuple of character values or an instance of ClassFunction_gap

• action – a function (default: operator.mul)

• action_on_basis – (optional) define the action of g on the basis of self

• side'left' or 'right' (default: 'right'); which side of self the elements of S acts

OUTPUT:

EXAMPLES:

sage: M = CombinatorialFreeModule(QQ, [1,2,3])                          # optional - sage.groups sage.modules
sage: G = SymmetricGroup(3)                                             # optional - sage.groups
sage: def action(g,x): return(M.term(g(x)))  # permute coordinates
sage: T = M.twisted_invariant_module(G, [2,0,-1],                       # optional - sage.groups sage.modules
....:                                action_on_basis=action)
sage: import __main__; __main__.action = action
sage: TestSuite(T).run()                                                # optional - sage.groups sage.modules

class TensorProducts(category, *args)#
extra_super_categories()#

Implement the fact that a (finite) tensor product of finite dimensional modules is a finite dimensional module.

EXAMPLES:

sage: C = ModulesWithBasis(ZZ).FiniteDimensional().TensorProducts()
sage: C.extra_super_categories()
[Category of finite dimensional modules with basis over Integer Ring]
sage: C.FiniteDimensional()
Category of tensor products of
finite dimensional modules with basis over Integer Ring