Free modules

class sage.combinat.free_module.CartesianProductWithFlattening(flatten)

Bases: object

A class for cartesian product constructor, with partial flattening

class sage.combinat.free_module.CombinatorialFreeModule(R, basis_keys, element_class=None, category=None, **kwds)

Bases: sage.structure.unique_representation.UniqueRepresentation, sage.modules.module.Module

Class for free modules with a named basis

INPUT:

  • R - base ring
  • basis_keys - list, tuple, family, set, etc. defining the indexing set for the basis of this module
  • element_class - the class of which elements of this module should be instances (optional, default None, in which case the elements are instances of CombinatorialFreeModuleElement)
  • category - the category in which this module lies (optional, default None, in which case use the “category of modules with basis” over the base ring R)

Options controlling the printing of elements:

  • prefix - string, prefix used for printing elements of this module (optional, default ‘B’). With the default, a monomial indexed by ‘a’ would be printed as B['a'].
  • latex_prefix - string or None, prefix used in the LaTeX representation of elements (optional, default None). If this is anything except the empty string, it prints the index as a subscript. If this is None, it uses the setting for prefix, so if prefix is set to “B”, then a monomial indexed by ‘a’ would be printed as B_{a}. If this is the empty string, then don’t print monomials as subscripts: the monomial indexed by ‘a’ would be printed as a, or as [a] if latex_bracket is True.
  • bracket - None, bool, string, or list or tuple of strings (optional, default None): if None, use the value of the attribute self._repr_option_bracket, which has default value True. (self._repr_option_bracket is available for backwards compatibility. Users should set bracket instead. If bracket is set to anything except None, it overrides the value of self._repr_option_bracket.) If False, do not include brackets when printing elements: a monomial indexed by ‘a’ would be printed as B'a', and a monomial indexed by (1,2,3) would be printed as B(1,2,3). If True, use “[” and “]” as brackets. If it is one of “[”, “(”, or “{”, use it and its partner as brackets. If it is any other string, use it as both brackets. If it is a list or tuple of strings, use the first entry as the left bracket and the second entry as the right bracket.
  • latex_bracket - bool, string, or list or tuple of strings (optional, default False): if False, do not include brackets in the LaTeX representation of elements. This option is only relevant if latex_prefix is the empty string; otherwise, brackets are not used regardless. If True, use “\left[” and “\right]” as brackets. If this is one of “[”, “(”, “\{”, “|”, or “||”, use it and its partner, prepended with “\left” and “\right”, as brackets. If this is any other string, use it as both brackets. If this is a list or tuple of strings, use the first entry as the left bracket and the second entry as the right bracket.
  • scalar_mult - string to use for scalar multiplication in the print representation (optional, default “*”)
  • latex_scalar_mult - string or None (optional, default None), string to use for scalar multiplication in the latex representation. If None, use the empty string if scalar_mult is set to “*”, otherwise use the value of scalar_mult.
  • tensor_symbol - string or None (optional, default None), string to use for tensor product in the print representation. If None, use the sage.categories.tensor.symbol.
  • monomial_cmp - a comparison function (optional, default cmp), to use for sorting elements in the output of elements

Note

These print options may also be accessed and modified using the print_options() method, after the module has been defined.

EXAMPLES:

We construct a free module whose basis is indexed by the letters a, b, c:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: F
Free module generated by {'a', 'b', 'c'} over Rational Field

Its basis is a family, indexed by a, b, c:

sage: e = F.basis()
sage: e
Finite family {'a': B['a'], 'c': B['c'], 'b': B['b']}
sage: [x for x in e]
[B['a'], B['b'], B['c']]
sage: [k for k in e.keys()]
['a', 'b', 'c']

Let us construct some elements, and compute with them:

sage: e['a']
B['a']
sage: 2*e['a']
2*B['a']
sage: e['a'] + 3*e['b']
B['a'] + 3*B['b']

Some uses of sage.categories.commutative_additive_semigroups.CommutativeAdditiveSemigroups.ParentMethods.summation() and sum():

sage: F = CombinatorialFreeModule(QQ, [1,2,3,4])
sage: F.summation(F.monomial(1), F.monomial(3))
B[1] + B[3]

sage: F = CombinatorialFreeModule(QQ, [1,2,3,4])
sage: F.sum(F.monomial(i) for i in [1,2,3])
B[1] + B[2] + B[3]

Note that free modules with a given basis and parameters are unique:

sage: F1 = CombinatorialFreeModule(QQ, (1,2,3,4))
sage: F1 is F
True

The identity of the constructed free module depends on the order of the basis and on the other parameters, like the prefix. Note that CombinatorialFreeModule is a UniqueRepresentation. Hence, two combinatorial free modules evaluate equal if and only if they are identical:

sage: F1 = CombinatorialFreeModule(QQ, (1,2,3,4))
sage: F1 is F
True
sage: F1 = CombinatorialFreeModule(QQ, [4,3,2,1])
sage: F1 == F
False
sage: F2 = CombinatorialFreeModule(QQ, [1,2,3,4], prefix='F')
sage: F2 == F
False

Because of this, if you create a free module with certain parameters and then modify its prefix or other print options, this affects all modules which were defined using the same parameters.

sage: F2.print_options(prefix='x')
sage: F2.prefix()
'x'
sage: F3 = CombinatorialFreeModule(QQ, [1,2,3,4], prefix='F')
sage: F3 is F2   # F3 was defined just like F2
True
sage: F3.prefix()
'x'
sage: F4 = CombinatorialFreeModule(QQ, [1,2,3,4], prefix='F', bracket=True)
sage: F4 == F2   # F4 was NOT defined just like F2
False
sage: F4.prefix()
'F'

sage: F2.print_options(prefix='F') #reset for following doctests

The default category is the category of modules with basis over the base ring:

sage: CombinatorialFreeModule(GF(3), ((1,2), (3,4))).category()
Category of modules with basis over Finite Field of size 3

See sage.categories.examples.algebras_with_basis and sage.categories.examples.hopf_algebras_with_basis for illustrations of the use of the category keyword, and see sage.combinat.root_system.weight_space.WeightSpace for an example of the use of element_class.

Customizing print and LaTeX representations of elements:

sage: F = CombinatorialFreeModule(QQ, ['a','b'], prefix='x')
sage: original_print_options = F.print_options()
sage: sorted(original_print_options.items())
 [('bracket', None), ('latex_bracket', False), ('latex_prefix', None), ('latex_scalar_mult', None), ('monomial_cmp', <built-in function cmp>), ('prefix', 'x'), ('scalar_mult', '*'), ('tensor_symbol', None)]

sage: e = F.basis()
sage: e['a'] - 3 * e['b']
x['a'] - 3*x['b']

sage: F.print_options(prefix='x', scalar_mult=' ', bracket='{')
sage: e['a'] - 3 * e['b']
x{'a'} - 3 x{'b'}
sage: latex(e['a'] - 3 * e['b'])
x_{a} - 3 x_{b}

sage: F.print_options(latex_prefix='y')
sage: latex(e['a'] - 3 * e['b'])
y_{a} - 3  y_{b}

sage: F.print_options(monomial_cmp = lambda x,y: -cmp(x,y))
sage: e['a'] - 3 * e['b']
-3 x{'b'} + x{'a'}
sage: F.print_options(**original_print_options) # reset print options

sage: F = CombinatorialFreeModule(QQ, [(1,2), (3,4)])
sage: e = F.basis()
sage: e[(1,2)] - 3 * e[(3,4)]
B[(1, 2)] - 3*B[(3, 4)]

sage: F.print_options(bracket=['_{', '}'])
sage: e[(1,2)] - 3 * e[(3,4)]
B_{(1, 2)} - 3*B_{(3, 4)}

sage: F.print_options(prefix='', bracket=False)
sage: e[(1,2)] - 3 * e[(3,4)]
(1, 2) - 3*(3, 4)

TESTS:

Before trac ticket #14054, combinatorial free modules violated the unique parent condition. That caused a problem. The tensor product construction involves maps, but maps check that their domain and the parent of a to-be-mapped element are identical (not just equal). However, the tensor product was cached by a cached_method, which involves comparison by equality (not identity). Hence, the last line of the following example used to fail with an assertion error:

sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix="F")
sage: G = CombinatorialFreeModule(ZZ, [1,2,3,4], prefix="G")
sage: f =   F.monomial(1) + 2 * F.monomial(2)
sage: g = 2*G.monomial(3) +     G.monomial(4)
sage: tensor([f, g])
2*F[1] # G[3] + F[1] # G[4] + 4*F[2] # G[3] + 2*F[2] # G[4]
sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='x')
sage: G = CombinatorialFreeModule(ZZ, [1,2,3,4], prefix='y')
sage: f =   F.monomial(1) + 2 * F.monomial(2)
sage: g = 2*G.monomial(3) +     G.monomial(4)
sage: tensor([f, g])
2*x[1] # y[3] + x[1] # y[4] + 4*x[2] # y[3] + 2*x[2] # y[4]
CartesianProduct

alias of CombinatorialFreeModule_CartesianProduct

Element

alias of CombinatorialFreeModuleElement

Tensor

alias of CombinatorialFreeModule_Tensor

dimension()

Returns the dimension of the combinatorial algebra (which is given by the number of elements in the basis).

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
sage: F.dimension()
3
sage: F.basis().cardinality()
3
sage: F.basis().keys().cardinality()
3
sage: s = SymmetricFunctions(QQ).schur()
sage: s.dimension()
+Infinity
from_vector(vector)

Build an element of self from a (sparse) vector

See also

get_order(), CombinatorialFreeModule.Element._vector_()

EXAMPLES:

sage: QS3 = SymmetricGroupAlgebra(QQ, 3)
sage: b = QS3.from_vector(vector((2, 0, 0, 0, 0, 4))); b
2*[1, 2, 3] + 4*[3, 2, 1]
sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1])
sage: a == b
True
gens()

Return a tuple consisting of the basis elements of self.

EXAMPLES:

sage: F = CombinatorialFreeModule(ZZ, ['a', 'b', 'c'])
sage: F.gens()
(B['a'], B['b'], B['c'])
get_order()

Returns the order of the elements in the basis.

EXAMPLES:

sage: QS2 = SymmetricGroupAlgebra(QQ,2)
sage: QS2.get_order()                    # note: order changed on 2009-03-13
[[2, 1], [1, 2]]
linear_combination(iter_of_elements_coeff, factor_on_left=True)

INPUT:

  • iter_of_elements_coeff – iterator of pairs (element, coeff) with element in self and coeff in self.base_ring()
  • factor_on_left (optional) – if True, the coefficients are multiplied from the left if False, the coefficients are multiplied from the right

Returns the linear combination \(\lambda_1 v_1 + ... + \lambda_k v_k\) (resp. the linear combination \(v_1 \lambda_1 + ... + v_k \lambda_k\)) where iter_of_elements_coeff iterates through the sequence \((\lambda_1, v_1) ... (\lambda_k, v_k)\).

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ,[1,2])
sage: f = F.an_element(); f
2*B[1] + 2*B[2]
sage: F.linear_combination( (f,i) for i in range(5) )
20*B[1] + 20*B[2]
monomial()

INPUT:

  • ‘’i’‘

Returns the basis element indexed by i

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
sage: F.monomial('a')
B['a']

F.monomial is in fact (almost) a map:

sage: F.monomial
Term map from {'a', 'b', 'c'} to Free module generated by {'a', 'b', 'c'} over Rational Field
monomial_or_zero_if_none(i)

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
sage: F.monomial_or_zero_if_none('a')
B['a']
sage: F.monomial_or_zero_if_none(None)
0
prefix()

Returns the prefix used when displaying elements of self.

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
sage: F.prefix()
'B'
sage: X = SchubertPolynomialRing(QQ)
sage: X.prefix()
'X'
print_options(**kwds)

Return the current print options, or set an option.

INPUT: all of the input is optional; if present, it should be in the form of keyword pairs, such as latex_bracket='('. The allowable keywords are:

  • prefix
  • latex_prefix
  • bracket
  • latex_bracket
  • scalar_mult
  • latex_scalar_mult
  • tensor_symbol
  • monomial_cmp

See the documentation for CombinatorialFreeModule for descriptions of the effects of setting each of these options.

OUTPUT: if the user provides any input, set the appropriate option(s) and return nothing. Otherwise, return the dictionary of settings for print and LaTeX representations.

EXAMPLES:

sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='x')
sage: F.print_options()
{...'prefix': 'x'...}
sage: F.print_options(bracket='(')
sage: F.print_options()
{...'bracket': '('...}

TESTS:

sage: sorted(F.print_options().items())
[('bracket', '('), ('latex_bracket', False), ('latex_prefix', None), ('latex_scalar_mult', None), ('monomial_cmp', <built-in function cmp>), ('prefix', 'x'), ('scalar_mult', '*'), ('tensor_symbol', None)]
sage: F.print_options(bracket='[') # reset
set_order(order)

Sets the order of the elements of the basis.

If set_order() has not been called, then the ordering is the one used in the generation of the elements of self’s associated enumerated set.

EXAMPLES:

sage: QS2 = SymmetricGroupAlgebra(QQ,2)
sage: b = list(QS2.basis().keys())
sage: b.reverse()
sage: QS2.set_order(b)
sage: QS2.get_order()
[[2, 1], [1, 2]]
sum(iter_of_elements)

overrides method inherited from commutative additive monoid as it is much faster on dicts directly

INPUT:

  • iter_of_elements: iterator of elements of self

Returns the sum of all elements in iter_of_elements

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ,[1,2])
sage: f = F.an_element(); f
2*B[1] + 2*B[2]
sage: F.sum( f for _ in range(5) )
10*B[1] + 10*B[2]
sum_of_monomials()

INPUT:

  • ‘’indices’’ – an list (or iterable) of indices of basis elements

Returns the sum of the corresponding basis elements

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
sage: F.sum_of_monomials(['a', 'b'])
B['a'] + B['b']

sage: F.sum_of_monomials(['a', 'b', 'a'])
2*B['a'] + B['b']

F.sum_of_monomials is in fact (almost) a map:

sage: F.sum_of_monomials
A map to Free module generated by {'a', 'b', 'c'} over Rational Field
sum_of_terms(terms, distinct=False)

Constructs a sum of terms of self

INPUT:

  • terms – a list (or iterable) of pairs (index, coeff)
  • distinct – whether the indices are guaranteed to be distinct (default: False)

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
sage: F.sum_of_terms([('a',2), ('c',3)])
2*B['a'] + 3*B['c']

If distinct is True, then the construction is optimized:

sage: F.sum_of_terms([('a',2), ('c',3)], distinct = True)
2*B['a'] + 3*B['c']

Warning

Use distinct=True only if you are sure that the indices are indeed distinct:

sage: F.sum_of_terms([('a',2), ('a',3)], distinct = True)
3*B['a']

Extreme case:

sage: F.sum_of_terms([])
0
term(index, coeff=None)

Constructs a term in self

INPUT:

  • index – the index of a basis element
  • coeff – an element of the coefficient ring (default: one)

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
sage: F.term('a',3)
3*B['a']
sage: F.term('a')
B['a']

Design: should this do coercion on the coefficient ring?

zero()

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
sage: F.zero()
0
class sage.combinat.free_module.CombinatorialFreeModuleElement(M, x)

Bases: sage.structure.element.Element

Create a combinatorial module element. This should never be called directly, but only through the parent combinatorial free module’s __call__() method.

TESTS:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] + 3*B['c']; f
B['a'] + 3*B['c']
sage: f == loads(dumps(f))
True
coefficient(m)

EXAMPLES:

sage: s = CombinatorialFreeModule(QQ, Partitions())
sage: z = s([4]) - 2*s([2,1]) + s([1,1,1]) + s([1])
sage: z.coefficient([4])
1
sage: z.coefficient([2,1])
-2
sage: z.coefficient(Partition([2,1]))
-2
sage: z.coefficient([1,2])
Traceback (most recent call last):
...
AssertionError: [1, 2] should be an element of Partitions
sage: z.coefficient(Composition([2,1]))
Traceback (most recent call last):
...
AssertionError: [2, 1] should be an element of Partitions

Test that coefficient also works for those parents that do not yet have an element_class:

sage: G = DihedralGroup(3)
sage: F = CombinatorialFreeModule(QQ, G)
sage: hasattr(G, "element_class")
False
sage: g = G.an_element()
sage: (2*F.monomial(g)).coefficient(g)
2
coefficients()

Returns a list of the coefficients appearing on the basis elements in self.

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] - 3*B['c']
sage: f.coefficients()
[1, -3]
sage: s = SymmetricFunctions(QQ).schur()
sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
sage: z.coefficients()
[1, 1, 1, 1]
is_zero()

Returns True if and only self == 0.

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] - 3*B['c']
sage: f.is_zero()
False
sage: F.zero().is_zero()
True
sage: s = SymmetricFunctions(QQ).schur()
sage: s([2,1]).is_zero()
False
sage: s(0).is_zero()
True
sage: (s([2,1]) - s([2,1])).is_zero()
True
length()

Returns the number of basis elements of self with nonzero coefficients.

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] - 3*B['c']
sage: f.length()
2
sage: s = SymmetricFunctions(QQ).schur()
sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
sage: z.length()
4
monomial_coefficients()

Return the internal dictionary which has the combinatorial objects indexing the basis as keys and their corresponding coefficients as values.

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] + 3*B['c']
sage: d = f.monomial_coefficients()
sage: d['a']
1
sage: d['c']
3

To run through the monomials of an element, it is better to use the idiom:

sage: for (t,c) in f:
...       print t,c
a 1
c 3
sage: s = SymmetricFunctions(QQ).schur()
sage: a = s([2,1])+2*s([3,2])
sage: d = a.monomial_coefficients()
sage: type(d)
<type 'dict'>
sage: d[ Partition([2,1]) ]
1
sage: d[ Partition([3,2]) ]
2
monomials()

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] + 2*B['c']
sage: f.monomials()
[B['a'], B['c']]

sage: (F.zero()).monomials()
[]
support()

Returns a list of the combinatorial objects indexing the basis elements of self which non-zero coefficients.

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] - 3*B['c']
sage: f.support()
['a', 'c']
sage: s = SymmetricFunctions(QQ).schur()
sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
sage: z.support()
[[1], [1, 1, 1], [2, 1], [4]]
terms()

Returns a list of the terms of self

See also

monomials()

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] + 2*B['c']
sage: f.terms()
[B['a'], 2*B['c']]
to_vector(new_base_ring=None)

Returns self as a dense vector

INPUT:

  • new_base_ring – a ring (default: None)

OUTPUT: a dense FreeModule() vector

Warning

This will crash/run forever if self is infinite dimensional!

See also

EXAMPLES:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] - 3*B['c']
sage: f._vector_()
(1, 0, -3)

One can use equivalently:

sage: f.to_vector()
(1, 0, -3)
sage: vector(f)
(1, 0, -3)

More examples:

sage: QS3 = SymmetricGroupAlgebra(QQ, 3)
sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1])
sage: a._vector_()
(2, 0, 0, 0, 0, 4)
sage: a.to_vector()
(2, 0, 0, 0, 0, 4)
sage: vector(a)
(2, 0, 0, 0, 0, 4)
sage: a == QS3.from_vector(a.to_vector())
True

If ‘’new_base_ring’’ is specified, then a vector over ‘’new_base_ring’’ is returned:

sage: a._vector_(RDF)
(2.0, 0.0, 0.0, 0.0, 0.0, 4.0)

Note

#13406: the current implementation has been optimized, at #the price of breaking the encapsulation for FreeModule elements creation, with the following use case as metric, on a 2008’ Macbook Pro:

   sage: F = CombinatorialFreeModule(QQ, range(10))
   sage: f = F.an_element()
   sage: %timeit f._vector_()   # not tested
   625 loops, best of 3: 17.5 micros per loop

Other use cases may call for different or further
optimizations.
class sage.combinat.free_module.CombinatorialFreeModule_CartesianProduct(modules, **options)

Bases: sage.combinat.free_module.CombinatorialFreeModule

An implementation of cartesian products of modules with basis

EXAMPLES:

We construct two free modules, assign them short names, and construct their cartesian product:

sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.__custom_name = "F"
sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.__custom_name = "G"
sage: H = CombinatorialFreeModule(ZZ, [4,7]); H.__custom_name = "H"
sage: S = cartesian_product([F, G])
sage: S
F (+) G
sage: S.basis()
Lazy family (Term map from Disjoint union of Family ({4, 5}, {4, 6}) to F (+) G(i))_{i in Disjoint union of Family ({4, 5}, {4, 6})}

Note that the indices of the basis elements of F and G intersect non trivially. This is handled by forcing the union to be disjoint:

sage: list(S.basis())
[B[(0, 4)], B[(0, 5)], B[(1, 4)], B[(1, 6)]]

We now compute the cartesian product of elements of free modules:

sage: f =   F.monomial(4) + 2 * F.monomial(5)
sage: g = 2*G.monomial(4) +     G.monomial(6)
sage: h =   H.monomial(4) +     H.monomial(7)
sage: cartesian_product([f,g])
B[(0, 4)] + 2*B[(0, 5)] + 2*B[(1, 4)] + B[(1, 6)]
sage: cartesian_product([f,g,h])
B[(0, 4)] + 2*B[(0, 5)] + 2*B[(1, 4)] + B[(1, 6)] + B[(2, 4)] + B[(2, 7)]
sage: cartesian_product([f,g,h]).parent()
F (+) G (+) H

TODO: choose an appropriate semantic for cartesian products of cartesian products (associativity?):

sage: S = cartesian_product([cartesian_product([F, G]), H]) # todo: not implemented
F (+) G (+) H
class Element(M, x)

Bases: sage.combinat.free_module.CombinatorialFreeModuleElement

Create a combinatorial module element. This should never be called directly, but only through the parent combinatorial free module’s __call__() method.

TESTS:

sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
sage: B = F.basis()
sage: f = B['a'] + 3*B['c']; f
B['a'] + 3*B['c']
sage: f == loads(dumps(f))
True
CombinatorialFreeModule_CartesianProduct.summand_embedding(i)

Returns the natural embedding morphism of the i-th summand of self into self

INPUTS:

  • i – an integer

EXAMPLES:

sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.__custom_name = "F"
sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.__custom_name = "G"
sage: S = cartesian_product([F, G])
sage: phi = S.summand_embedding(0)
sage: phi(F.monomial(4) + 2 * F.monomial(5))
B[(0, 4)] + 2*B[(0, 5)]
sage: phi(F.monomial(4) + 2 * F.monomial(6)).parent() == S
True
sage: phi(G.monomial(4)) # not implemented Should raise an error!  problem: G(F.monomial(4)) does not complain!!!!
CombinatorialFreeModule_CartesianProduct.summand_projection(i)

Returns the natural projection onto the i-th summand of self

INPUTS:

  • i – an integer

EXAMPLE:

sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.__custom_name = "F"
sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.__custom_name = "G"
sage: S = cartesian_product([F, G])
sage: x = S.monomial((0,4)) + 2 * S.monomial((0,5)) + 3 * S.monomial((1,6))
sage: S.summand_projection(0)(x)
B[4] + 2*B[5]
sage: S.summand_projection(1)(x)
3*B[6]
sage: S.summand_projection(0)(x).parent() == F
True
sage: S.summand_projection(1)(x).parent() == G
True
class sage.combinat.free_module.CombinatorialFreeModule_Tensor(modules, **options)

Bases: sage.combinat.free_module.CombinatorialFreeModule

Tensor Product of Free Modules

EXAMPLES:

We construct two free modules, assign them short names, and construct their tensor product:

sage: F = CombinatorialFreeModule(ZZ, [1,2]); F.__custom_name = "F"
sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.__custom_name = "G"
sage: T = tensor([F, G]); T
F # G

sage: T.category()
Category of tensor products of modules with basis over Integer Ring

sage: T.construction() # todo: not implemented
[tensor, ]

T is a free module, with same base ring as F and G:

sage: T.base_ring()
Integer Ring

The basis of T is indexed by tuples of basis indices of F and G:

sage: T.basis().keys()
Image of Cartesian product of {1, 2}, {3, 4} by <type 'tuple'>
sage: T.basis().keys().list()
[(1, 3), (1, 4), (2, 3), (2, 4)]

FIXME: Should elements of a CartesianProduct be tuples (making them hashable)?

Here are the basis elements themselves:

sage: T.basis().cardinality()
4
sage: list(T.basis())
[B[1] # B[3], B[1] # B[4], B[2] # B[3], B[2] # B[4]]

The tensor product is associative and flattens sub tensor products:

sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename("H")
sage: tensor([F, tensor([G, H])])
F # G # H
sage: tensor([tensor([F, G]), H])
F # G # H
sage: tensor([F, G, H])
F # G # H

We now compute the tensor product of elements of free modules:

sage: f =   F.monomial(1) + 2 * F.monomial(2)
sage: g = 2*G.monomial(3) +     G.monomial(4)
sage: h =   H.monomial(5) +     H.monomial(6)
sage: tensor([f, g])
2*B[1] # B[3] + B[1] # B[4] + 4*B[2] # B[3] + 2*B[2] # B[4]

Again, the tensor product is associative on elements:

sage: tensor([f, tensor([g, h])]) == tensor([f, g, h])
True
sage: tensor([tensor([f, g]), h]) == tensor([f, g, h])
True

Note further that the tensor product spaces need not preexist:

sage: t = tensor([f, g, h])
sage: t.parent()
F # G # H

TESTS:

sage: tensor([tensor([F, G]), H]) == tensor([F, G, H])
True
sage: tensor([F, tensor([G, H])]) == tensor([F, G, H])
True
tensor_constructor(modules)

INPUT:

  • modules – a tuple \((F_1,\dots,F_n)\) of free modules whose tensor product is self

Returns the canonical multilinear morphism from \(F_1 \times \dots \times F_n\) to \(F_1 \otimes \dots \otimes F_n\)

EXAMPLES:

sage: F = CombinatorialFreeModule(ZZ, [1,2]); F.__custom_name = "F"
sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.__custom_name = "G"
sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename("H")

sage: f =   F.monomial(1) + 2 * F.monomial(2)
sage: g = 2*G.monomial(3) +     G.monomial(4)
sage: h =   H.monomial(5) +     H.monomial(6)
sage: FG  = tensor([F, G   ])
sage: phi_fg = FG.tensor_constructor((F, G))
sage: phi_fg(f,g)
2*B[1] # B[3] + B[1] # B[4] + 4*B[2] # B[3] + 2*B[2] # B[4]

sage: FGH = tensor([F, G, H])
sage: phi_fgh = FGH.tensor_constructor((F, G, H))
sage: phi_fgh(f, g, h)
2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6]

sage: phi_fg_h = FGH.tensor_constructor((FG, H))
sage: phi_fg_h(phi_fg(f, g), h)
2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6]

Previous topic

Combinatorial Algebras

Next topic

Combinatorial Algebras

This Page