Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Filtered Modules With Basis
A *filtered module with basis* over a ring `R` means (for the purpose of this code) a filtered `R`-module `M` with filtration `(F_i)_{i \in I}` (typically `I = \NN`) endowed with a basis `(b_j)_{j \in J}` of `M` and a partition `J = \bigsqcup_{i \in I} J_i` of the set `J` (it is allowed that some `J_i` are empty) such that for every `n \in I`, the subfamily `(b_j)_{j \in U_n}`, where `U_n = \bigcup_{i \leq n} J_i`, is a basis of the `R`-submodule `F_n`.
For every `i \in I`, the `R`-submodule of `M` spanned by `(b_j)_{j \in J_i}` is called the `i`-*th graded component* (aka the `i`-*th homogeneous component*) of the filtered module with basis `M`; the elements of this submodule are referred to as *homogeneous elements of degree* `i`.
See the class documentation :class:`~sage.categories.filtered_modules_with_basis.FilteredModulesWithBasis` for further details. """ #***************************************************************************** # Copyright (C) 2014 Travis Scrimshaw <tscrim at ucdavis.edu> # # Distributed under the terms of the GNU General Public License (GPL) # http://www.gnu.org/licenses/ #******************************************************************************
r""" The category of filtered modules with a distinguished basis.
A *filtered module with basis* over a ring `R` means (for the purpose of this code) a filtered `R`-module `M` with filtration `(F_i)_{i \in I}` (typically `I = \NN`) endowed with a basis `(b_j)_{j \in J}` of `M` and a partition `J = \bigsqcup_{i \in I} J_i` of the set `J` (it is allowed that some `J_i` are empty) such that for every `n \in I`, the subfamily `(b_j)_{j \in U_n}`, where `U_n = \bigcup_{i \leq n} J_i`, is a basis of the `R`-submodule `F_n`.
For every `i \in I`, the `R`-submodule of `M` spanned by `(b_j)_{j \in J_i}` is called the `i`-*th graded component* (aka the `i`-*th homogeneous component*) of the filtered module with basis `M`; the elements of this submodule are referred to as *homogeneous elements of degree* `i`. The `R`-module `M` is the direct sum of its `i`-th graded components over all `i \in I`, and thus becomes a graded `R`-module with basis. Conversely, any graded `R`-module with basis canonically becomes a filtered `R`-module with basis (by defining `F_n = \bigoplus_{i \leq n} G_i` where `G_i` is the `i`-th graded component, and defining `J_i` as the indexing set of the basis of the `i`-th graded component). Hence, the notion of a filtered `R`-module with basis is equivalent to the notion of a graded `R`-module with basis.
However, the *category* of filtered `R`-modules with basis is not the category of graded `R`-modules with basis. Indeed, the *morphisms* of filtered `R`-modules with basis are defined to be morphisms of `R`-modules which send each `F_n` of the domain to the corresponding `F_n` of the target; in contrast, the morphisms of graded `R`-modules with basis must preserve each homogeneous component. Also, the notion of a filtered algebra with basis differs from that of a graded algebra with basis.
.. NOTE::
Currently, to make use of the functionality of this class, an instance of ``FilteredModulesWithBasis`` should fulfill the contract of a :class:`CombinatorialFreeModule` (most likely by inheriting from it). It should also have the indexing set `J` encoded as its ``_indices`` attribute, and ``_indices.subset(size=i)`` should yield the subset `J_i` (as an iterable). If the latter conditions are not satisfied, then :meth:`basis` must be overridden.
.. NOTE::
One should implement a ``degree_on_basis`` method in the parent class in order to fully utilize the methods of this category. This might become a required abstract method in the future.
EXAMPLES::
sage: C = ModulesWithBasis(ZZ).Filtered(); C Category of filtered modules with basis over Integer Ring sage: sorted(C.super_categories(), key=str) [Category of filtered modules over Integer Ring, Category of modules with basis over Integer Ring] sage: C is ModulesWithBasis(ZZ).Filtered() True
TESTS::
sage: C = ModulesWithBasis(ZZ).Filtered() sage: TestSuite(C).run() sage: C = ModulesWithBasis(QQ).Filtered() sage: TestSuite(C).run() """ # TODO: which syntax do we prefer? # A.basis(degree = 3) # A.basis().subset(degree=3)
# This is related to the following design question: # If F = (f_i)_{i\in I} is a family, should ``F.subset(degree = 3)`` # be the elements of F of degree 3 or those whose index is of degree 3?
r""" Return the basis for (the ``d``-th homogeneous component of) ``self``.
INPUT:
- ``d`` -- (optional, default ``None``) nonnegative integer or ``None``
OUTPUT:
If ``d`` is ``None``, returns the basis of the module. Otherwise, returns the basis of the homogeneous component of degree ``d`` (i.e., the subfamily of the basis of the whole module which consists only of the basis vectors lying in `F_d \setminus \bigcup_{i<d} F_i`).
The basis is always returned as a family.
EXAMPLES::
sage: A = ModulesWithBasis(ZZ).Filtered().example() sage: A.basis(4) Lazy family (Term map from Partitions to An example of a filtered module with basis: the free module on partitions over Integer Ring(i))_{i in Partitions of the integer 4}
Without arguments, the full basis is returned::
sage: A.basis() Lazy family (Term map from Partitions to An example of a filtered module with basis: the free module on partitions over Integer Ring(i))_{i in Partitions} sage: A.basis() Lazy family (Term map from Partitions to An example of a filtered module with basis: the free module on partitions over Integer Ring(i))_{i in Partitions}
Checking this method on a filtered algebra. Note that this will typically raise a ``NotImplementedError`` when this feature is not implemented. ::
sage: A = AlgebrasWithBasis(ZZ).Filtered().example() sage: A.basis(4) Traceback (most recent call last): ... NotImplementedError: infinite set
Without arguments, the full basis is returned::
sage: A.basis() Lazy family (Term map from Free abelian monoid indexed by {'x', 'y', 'z'} to An example of a filtered algebra with basis: the universal enveloping algebra of Lie algebra of RR^3 with cross product over Integer Ring(i))_{i in Free abelian monoid indexed by {'x', 'y', 'z'}}
An example with a graded algebra::
sage: E.<x,y> = ExteriorAlgebra(QQ) sage: E.basis() Lazy family (Term map from Subsets of {0, 1} to The exterior algebra of rank 2 over Rational Field(i))_{i in Subsets of {0, 1}} """ else:
# TODO: Change `list(self._indices)` to `self._indices` and move # this fallback to the category of finite-dimensional filtered # modules with basis when it is implemented and the MRO issues # are fixed (see trac #19397) """ Return a basis for the ``d``-th homogeneous component of ``self``.
EXAMPLES::
sage: A = GradedModulesWithBasis(ZZ).example() sage: A.homogeneous_component_basis(4) Lazy family (Term map from Partitions to An example of a graded module with basis: the free module on partitions over Integer Ring(i))_{i in Partitions of the integer 4}
sage: cat = GradedModulesWithBasis(ZZ) sage: C = CombinatorialFreeModule(ZZ, ['a', 'b'], category=cat) sage: C.degree_on_basis = lambda x: 1 if x == 'a' else 2 sage: C.homogeneous_component_basis(1) Finite family {'a': B['a']} sage: C.homogeneous_component_basis(2) Finite family {'b': B['b']} """
""" Return the ``d``-th homogeneous component of ``self``.
EXAMPLES::
sage: A = GradedModulesWithBasis(ZZ).example() sage: A.homogeneous_component(4) Degree 4 homogeneous component of An example of a graded module with basis: the free module on partitions over Integer Ring """ raise NotImplementedError("this is only a natural module over" " the degree 0 component of the filtered" " algebra and coordinate rings are not" " yet implemented for submodules") category=category, already_echelonized=True)
r""" Return the associated graded module to ``self``.
See :class:`~sage.algebras.associated_graded.AssociatedGradedAlgebra` for the definition and the properties of this.
If the filtered module ``self`` with basis is called `A`, then this method returns `\operatorname{gr} A`. The method :meth:`to_graded_conversion` returns the canonical `R`-module isomorphism `A \to \operatorname{gr} A` induced by the basis of `A`, and the method :meth:`from_graded_conversion` returns the inverse of this isomorphism. The method :meth:`projection` projects elements of `A` onto `\operatorname{gr} A` according to their place in the filtration on `A`.
.. WARNING::
When not overridden, this method returns the default implementation of an associated graded module -- namely, ``AssociatedGradedAlgebra(self)``, where ``AssociatedGradedAlgebra`` is :class:`~sage.algebras.associated_graded.AssociatedGradedAlgebra`. But some instances of :class:`FilteredModulesWithBasis` override this method, as the associated graded module often is (isomorphic) to a simpler object (for instance, the associated graded module of a graded module can be identified with the graded module itself). Generic code that uses associated graded modules (such as the code of the :meth:`induced_graded_map` method below) should make sure to only communicate with them via the :meth:`to_graded_conversion`, :meth:`from_graded_conversion` and :meth:`projection` methods (in particular, do not expect there to be a conversion from ``self`` to ``self.graded_algebra()``; this currently does not work for Clifford algebras). Similarly, when overriding :meth:`graded_algebra`, make sure to accordingly redefine these three methods, unless their definitions below still apply to your case (this will happen whenever the basis of your :meth:`graded_algebra` has the same indexing set as ``self``, and the partition of this indexing set according to degree is the same as for ``self``).
EXAMPLES::
sage: A = ModulesWithBasis(ZZ).Filtered().example() sage: A.graded_algebra() Graded Module of An example of a filtered module with basis: the free module on partitions over Integer Ring """
# Maps
r""" Return the canonical `R`-module isomorphism `A \to \operatorname{gr} A` induced by the basis of `A` (where `A = ` ``self``).
This is an isomorphism of `R`-modules. See the class documentation :class:`AssociatedGradedAlgebra`.
.. SEEALSO::
:meth:`from_graded_conversion`
EXAMPLES::
sage: A = Modules(QQ).WithBasis().Filtered().example() sage: p = -2 * A.an_element(); p -4*P[] - 4*P[1] - 6*P[2] sage: q = A.to_graded_conversion()(p); q -4*Bbar[[]] - 4*Bbar[[1]] - 6*Bbar[[2]] sage: q.parent() is A.graded_algebra() True """ codomain=self.graded_algebra())
r""" Return the inverse of the canonical `R`-module isomorphism `A \to \operatorname{gr} A` induced by the basis of `A` (where `A = ` ``self``). This inverse is an isomorphism `\operatorname{gr} A \to A`.
This is an isomorphism of `R`-modules. See the class documentation :class:`AssociatedGradedAlgebra`.
.. SEEALSO::
:meth:`to_graded_conversion`
EXAMPLES::
sage: A = Modules(QQ).WithBasis().Filtered().example() sage: p = -2 * A.an_element(); p -4*P[] - 4*P[1] - 6*P[2] sage: q = A.to_graded_conversion()(p); q -4*Bbar[[]] - 4*Bbar[[1]] - 6*Bbar[[2]] sage: A.from_graded_conversion()(q) == p True sage: q.parent() is A.graded_algebra() True """ codomain=self)
r""" Return the `i`-th projection `p_i : F_i \to G_i` (in the notations of the class documentation :class:`AssociatedGradedAlgebra`, where `A = ` ``self``).
This method actually does not return the map `p_i` itself, but an extension of `p_i` to the whole `R`-module `A`. This extension is the composition of the `R`-module isomorphism `A \to \operatorname{gr} A` with the canonical projection of the graded `R`-module `\operatorname{gr} A` onto its `i`-th graded component `G_i`. The codomain of this map is `\operatorname{gr} A`, although its actual image is `G_i`. The map `p_i` is obtained from this map by restricting its domain to `F_i` and its image to `G_i`.
EXAMPLES::
sage: A = Modules(ZZ).WithBasis().Filtered().example() sage: p = -2 * A.an_element(); p -4*P[] - 4*P[1] - 6*P[2] sage: q = A.projection(2)(p); q -6*Bbar[[2]] sage: q.parent() is A.graded_algebra() True sage: A.projection(3)(p) 0 """ else base_zero)
r""" Return the graded linear map between the associated graded modules of ``self`` and ``other`` canonically induced by the filtration-preserving map ``f : self -> other``.
Let `A` and `B` be two filtered modules with basis, and let `(F_i)_{i \in I}` and `(G_i)_{i \in I}` be their filtrations. Let `f : A \to B` be a linear map which preserves the filtration (i.e., satisfies `f(F_i) \subseteq G_i` for all `i \in I`). Then, there is a canonically defined graded linear map `\operatorname{gr} f : \operatorname{gr} A \to \operatorname{gr} B` which satisfies
.. MATH::
(\operatorname{gr} f) (p_i(a)) = p_i(f(a)) \qquad \text{for all } i \in I \text{ and } a \in F_i ,
where the `p_i` on the left hand side is the canonical projection from `F_i` onto the `i`-th graded component of `\operatorname{gr} A`, while the `p_i` on the right hand side is the canonical projection from `G_i` onto the `i`-th graded component of `\operatorname{gr} B`.
INPUT:
- ``other`` -- a filtered algebra with basis
- ``f`` -- a filtration-preserving linear map from ``self`` to ``other`` (can be given as a morphism or as a function)
OUTPUT:
The graded linear map `\operatorname{gr} f`.
EXAMPLES:
**Example 1.**
We start with the free `\QQ`-module with basis the set of all partitions::
sage: A = Modules(QQ).WithBasis().Filtered().example(); A An example of a filtered module with basis: the free module on partitions over Rational Field sage: M = A.indices(); M Partitions sage: p1, p2, p21, p321 = [A.basis()[Partition(i)] for i in [[1], [2], [2,1], [3,2,1]]]
Let us define a map from ``A`` to itself which acts on the basis by sending every partition `\lambda` to the sum of the conjugates of all partitions `\mu` for which `\lambda / \mu` is a horizontal strip::
sage: def map_on_basis(lam): ....: return A.sum_of_monomials([Partition(mu).conjugate() for k in range(sum(lam) + 1) ....: for mu in lam.remove_horizontal_border_strip(k)]) sage: f = A.module_morphism(on_basis=map_on_basis, ....: codomain=A) sage: f(p1) P[] + P[1] sage: f(p2) P[] + P[1] + P[1, 1] sage: f(p21) P[1] + P[1, 1] + P[2] + P[2, 1] sage: f(p21 - p1) -P[] + P[1, 1] + P[2] + P[2, 1] sage: f(p321) P[2, 1] + P[2, 1, 1] + P[2, 2] + P[2, 2, 1] + P[3, 1] + P[3, 1, 1] + P[3, 2] + P[3, 2, 1]
We now compute `\operatorname{gr} f` ::
sage: grA = A.graded_algebra(); grA Graded Module of An example of a filtered module with basis: the free module on partitions over Rational Field sage: pp1, pp2, pp21, pp321 = [A.to_graded_conversion()(i) for i in [p1, p2, p21, p321]] sage: pp2 + 4 * pp21 Bbar[[2]] + 4*Bbar[[2, 1]] sage: grf = A.induced_graded_map(A, f); grf Generic endomorphism of Graded Module of An example of a filtered module with basis: the free module on partitions over Rational Field sage: grf(pp1) Bbar[[1]] sage: grf(pp2 + 4 * pp21) Bbar[[1, 1]] + 4*Bbar[[2, 1]]
**Example 2.**
We shall now construct `\operatorname{gr} f` for a different map `f` out of the same ``A``; the new map `f` will lead into a graded algebra already, namely into the algebra of symmetric functions::
sage: h = SymmetricFunctions(QQ).h() sage: def map_on_basis(lam): # redefining map_on_basis ....: return h.sum_of_monomials([Partition(mu).conjugate() for k in range(sum(lam) + 1) ....: for mu in lam.remove_horizontal_border_strip(k)]) sage: f = A.module_morphism(on_basis=map_on_basis, ....: codomain=h) # redefining f sage: f(p1) h[] + h[1] sage: f(p2) h[] + h[1] + h[1, 1] sage: f(A.zero()) 0 sage: f(p2 - 3*p1) -2*h[] - 2*h[1] + h[1, 1]
The algebra ``h`` of symmetric functions in the `h`-basis is already graded, so its associated graded algebra is implemented as itself::
sage: grh = h.graded_algebra(); grh is h True sage: grf = A.induced_graded_map(h, f); grf Generic morphism: From: Graded Module of An example of a filtered module with basis: the free module on partitions over Rational Field To: Symmetric Functions over Rational Field in the homogeneous basis sage: grf(pp1) h[1] sage: grf(pp2) h[1, 1] sage: grf(pp321) h[3, 2, 1] sage: grf(pp2 - 3*pp1) -3*h[1] + h[1, 1] sage: grf(pp21) h[2, 1] sage: grf(grA.zero()) 0
**Example 3.**
After having had a graded module as the codomain, let us try to have one as the domain instead. Our new ``f`` will go from ``h`` to ``A``::
sage: def map_on_basis(lam): # redefining map_on_basis ....: return A.sum_of_monomials([Partition(mu).conjugate() for k in range(sum(lam) + 1) ....: for mu in lam.remove_horizontal_border_strip(k)]) sage: f = h.module_morphism(on_basis=map_on_basis, ....: codomain=A) # redefining f sage: f(h[1]) P[] + P[1] sage: f(h[2]) P[] + P[1] + P[1, 1] sage: f(h[1, 1]) P[1] + P[2] sage: f(h[2, 2]) P[1, 1] + P[2, 1] + P[2, 2] sage: f(h[3, 2, 1]) P[2, 1] + P[2, 1, 1] + P[2, 2] + P[2, 2, 1] + P[3, 1] + P[3, 1, 1] + P[3, 2] + P[3, 2, 1] sage: f(h.one()) P[] sage: grf = h.induced_graded_map(A, f); grf Generic morphism: From: Symmetric Functions over Rational Field in the homogeneous basis To: Graded Module of An example of a filtered module with basis: the free module on partitions over Rational Field sage: grf(h[1]) Bbar[[1]] sage: grf(h[2]) Bbar[[1, 1]] sage: grf(h[1, 1]) Bbar[[2]] sage: grf(h[2, 2]) Bbar[[2, 2]] sage: grf(h[3, 2, 1]) Bbar[[3, 2, 1]] sage: grf(h.one()) Bbar[[]]
**Example 4.**
The construct `\operatorname{gr} f` also makes sense when `f` is a filtration-preserving map between graded modules. ::
sage: def map_on_basis(lam): # redefining map_on_basis ....: return h.sum_of_monomials([Partition(mu).conjugate() for k in range(sum(lam) + 1) ....: for mu in lam.remove_horizontal_border_strip(k)]) sage: f = h.module_morphism(on_basis=map_on_basis, ....: codomain=h) # redefining f sage: f(h[1]) h[] + h[1] sage: f(h[2]) h[] + h[1] + h[1, 1] sage: f(h[1, 1]) h[1] + h[2] sage: f(h[2, 1]) h[1] + h[1, 1] + h[2] + h[2, 1] sage: f(h.one()) h[] sage: grf = h.induced_graded_map(h, f); grf Generic endomorphism of Symmetric Functions over Rational Field in the homogeneous basis sage: grf(h[1]) h[1] sage: grf(h[2]) h[1, 1] sage: grf(h[1, 1]) h[2] sage: grf(h[2, 1]) h[2, 1] sage: grf(h.one()) h[] """ codomain=grB, category=cat) # If we could assume that the projection of the basis # element of ``self`` indexed by an index ``m`` is the # basis element of ``grA`` indexed by ``m``, then this # could go faster: # # def on_basis(m): # i = grA.degree_on_basis(m) # return grB.projection(i)(f(self.monomial(m))) # return grA.module_morphism(on_basis=on_basis, # codomain=grB, category=cat) # # But this assumption might come back to bite us in the # ass one day. What do you think?
r""" Return whether the element ``self`` is homogeneous.
EXAMPLES::
sage: A = ModulesWithBasis(ZZ).Filtered().example() sage: x=A(Partition((3,2,1))) sage: y=A(Partition((4,4,1))) sage: z=A(Partition((2,2,2))) sage: (3*x).is_homogeneous() True sage: (x - y).is_homogeneous() False sage: (x+2*z).is_homogeneous() True
Here is an example with a graded algebra::
sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: (x, y) = (S[2], S[3]) sage: (3*x).is_homogeneous() True sage: (x^3 - y^2).is_homogeneous() True sage: ((x + y)^2).is_homogeneous() False
Let us now test a filtered algebra (but remember that the notion of homogeneity now depends on the choice of a basis, or at least on a definition of homogeneous components)::
sage: A = AlgebrasWithBasis(QQ).Filtered().example() sage: x,y,z = A.algebra_generators() sage: (x*y).is_homogeneous() True sage: (y*x).is_homogeneous() False sage: A.one().is_homogeneous() True sage: A.zero().is_homogeneous() True sage: (A.one()+x).is_homogeneous() False """ else:
def degree_on_basis(self, m): r""" Return the degree of the basis element indexed by ``m`` in ``self``.
EXAMPLES::
sage: A = GradedModulesWithBasis(QQ).example() sage: A.degree_on_basis(Partition((2,1))) 3 sage: A.degree_on_basis(Partition((4,2,1,1,1,1))) 10 """
r""" The degree of a nonzero homogeneous element ``self`` in the filtered module.
.. NOTE::
This raises an error if the element is not homogeneous. To compute the maximum of the degrees of the homogeneous summands of a (not necessarily homogeneous) element, use :meth:`maximal_degree` instead.
EXAMPLES::
sage: A = ModulesWithBasis(ZZ).Filtered().example() sage: x = A(Partition((3,2,1))) sage: y = A(Partition((4,4,1))) sage: z = A(Partition((2,2,2))) sage: x.degree() 6 sage: (x + 2*z).degree() 6 sage: (y - x).degree() Traceback (most recent call last): ... ValueError: element is not homogeneous
An example in a graded algebra::
sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: (x, y) = (S[2], S[3]) sage: x.homogeneous_degree() 2 sage: (x^3 + 4*y^2).homogeneous_degree() 6 sage: ((1 + x)^3).homogeneous_degree() Traceback (most recent call last): ... ValueError: element is not homogeneous
Let us now test a filtered algebra (but remember that the notion of homogeneity now depends on the choice of a basis)::
sage: A = AlgebrasWithBasis(QQ).Filtered().example() sage: x,y,z = A.algebra_generators() sage: (x*y).homogeneous_degree() 2 sage: (y*x).homogeneous_degree() Traceback (most recent call last): ... ValueError: element is not homogeneous sage: A.one().homogeneous_degree() 0
TESTS::
sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: S.zero().degree() Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree """ raise ValueError("the zero element does not have a well-defined degree")
# default choice for degree; will be overridden as necessary
""" The maximum of the degrees of the homogeneous components of ``self``.
This is also the smallest `i` such that ``self`` belongs to `F_i`. Hence, it does not depend on the basis of the parent of ``self``.
.. SEEALSO:: :meth:`homogeneous_degree`
EXAMPLES:
sage: A = ModulesWithBasis(ZZ).Filtered().example() sage: x = A(Partition((3,2,1))) sage: y = A(Partition((4,4,1))) sage: z = A(Partition((2,2,2))) sage: x.maximal_degree() 6 sage: (x + 2*z).maximal_degree() 6 sage: (y - x).maximal_degree() 9 sage: (3*z).maximal_degree() 6
Now, we test this on a graded algebra::
sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: (x, y) = (S[2], S[3]) sage: x.maximal_degree() 2 sage: (x^3 + 4*y^2).maximal_degree() 6 sage: ((1 + x)^3).maximal_degree() 6
Let us now test a filtered algebra::
sage: A = AlgebrasWithBasis(QQ).Filtered().example() sage: x,y,z = A.algebra_generators() sage: (x*y).maximal_degree() 2 sage: (y*x).maximal_degree() 2 sage: A.one().maximal_degree() 0 sage: A.zero().maximal_degree() Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree sage: (A.one()+x).maximal_degree() 1
TESTS::
sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: S.zero().degree() Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree """
""" Return the homogeneous component of degree ``n`` of the element ``self``.
Let `m` be an element of a filtered `R`-module `M` with basis. Then, `m` can be uniquely written in the form `m = \sum_{i \in I} m_i`, where each `m_i` is a homogeneous element of degree `i`. For `n \in I`, we define the homogeneous component of degree `n` of the element `m` to be `m_n`.
EXAMPLES::
sage: A = ModulesWithBasis(ZZ).Filtered().example() sage: x = A.an_element(); x 2*P[] + 2*P[1] + 3*P[2] sage: x.homogeneous_component(-1) 0 sage: x.homogeneous_component(0) 2*P[] sage: x.homogeneous_component(1) 2*P[1] sage: x.homogeneous_component(2) 3*P[2] sage: x.homogeneous_component(3) 0
sage: A = ModulesWithBasis(ZZ).Graded().example() sage: x = A.an_element(); x 2*P[] + 2*P[1] + 3*P[2] sage: x.homogeneous_component(-1) 0 sage: x.homogeneous_component(0) 2*P[] sage: x.homogeneous_component(1) 2*P[1] sage: x.homogeneous_component(2) 3*P[2] sage: x.homogeneous_component(3) 0
sage: A = AlgebrasWithBasis(ZZ).Filtered().example() sage: G = A.algebra_generators() sage: g = A.an_element() - 2 * G['x'] * G['y']; g U['x']^2*U['y']^2*U['z']^3 - 2*U['x']*U['y'] + 2*U['x'] + 3*U['y'] + 1 sage: g.homogeneous_component(-1) 0 sage: g.homogeneous_component(0) 1 sage: g.homogeneous_component(2) -2*U['x']*U['y'] sage: g.homogeneous_component(5) 0 sage: g.homogeneous_component(7) U['x']^2*U['y']^2*U['z']^3 sage: g.homogeneous_component(8) 0
TESTS:
Check that this really returns ``A.zero()`` and not a plain ``0``::
sage: A = ModulesWithBasis(ZZ).Filtered().example() sage: x = A.an_element() sage: x.homogeneous_component(3).parent() is A True """ for (i, c) in self if degree_on_basis(i) == n)
""" Return the sum of the homogeneous components of degree strictly less than ``n`` of ``self``.
See :meth:`homogeneous_component` for the notion of a homogeneous component.
EXAMPLES::
sage: A = ModulesWithBasis(ZZ).Filtered().example() sage: x = A.an_element(); x 2*P[] + 2*P[1] + 3*P[2] sage: x.truncate(0) 0 sage: x.truncate(1) 2*P[] sage: x.truncate(2) 2*P[] + 2*P[1] sage: x.truncate(3) 2*P[] + 2*P[1] + 3*P[2]
sage: A = ModulesWithBasis(ZZ).Graded().example() sage: x = A.an_element(); x 2*P[] + 2*P[1] + 3*P[2] sage: x.truncate(0) 0 sage: x.truncate(1) 2*P[] sage: x.truncate(2) 2*P[] + 2*P[1] sage: x.truncate(3) 2*P[] + 2*P[1] + 3*P[2]
sage: A = AlgebrasWithBasis(ZZ).Filtered().example() sage: G = A.algebra_generators() sage: g = A.an_element() - 2 * G['x'] * G['y']; g U['x']^2*U['y']^2*U['z']^3 - 2*U['x']*U['y'] + 2*U['x'] + 3*U['y'] + 1 sage: g.truncate(-1) 0 sage: g.truncate(0) 0 sage: g.truncate(2) 2*U['x'] + 3*U['y'] + 1 sage: g.truncate(3) -2*U['x']*U['y'] + 2*U['x'] + 3*U['y'] + 1 sage: g.truncate(5) -2*U['x']*U['y'] + 2*U['x'] + 3*U['y'] + 1 sage: g.truncate(7) -2*U['x']*U['y'] + 2*U['x'] + 3*U['y'] + 1 sage: g.truncate(8) U['x']^2*U['y']^2*U['z']^3 - 2*U['x']*U['y'] + 2*U['x'] + 3*U['y'] + 1
TESTS:
Check that this really return ``A.zero()`` and not a plain ``0``::
sage: A = ModulesWithBasis(ZZ).Filtered().example() sage: x = A.an_element() sage: x.truncate(0).parent() is A True """ if degree_on_basis(i) < n)
|