diff --git a/src/sage/categories/filtered_modules_with_basis.py b/src/sage/categories/filtered_modules_with_basis.py index a4b6cbe036e..da9161f82b0 100644 --- a/src/sage/categories/filtered_modules_with_basis.py +++ b/src/sage/categories/filtered_modules_with_basis.py @@ -31,6 +31,8 @@ from sage.categories.filtered_modules import FilteredModulesCategory from sage.misc.abstract_method import abstract_method from sage.misc.cachefunc import cached_method +from sage.categories.subobjects import SubobjectsCategory +from sage.categories.quotients import QuotientsCategory class FilteredModulesWithBasis(FilteredModulesCategory): r""" @@ -392,6 +394,64 @@ def projection(self, i): else base_zero) return self.module_morphism(diagonal=proj, codomain=grA) + def filtered_submodule(self, gens): + r""" + Create a graded submodule by referencing the grading of + ``self``. The generators have to be each homogeneous. + + INPUTS:: + + - ``gens``: The generators of the submodule. + + EXAMPLES:: + + sage: M = ModulesWithBasis(QQ).Filtered().example() + sage: N = M.filtered_submodule([M(Partition((5,3))), M(Partition((4,2,1,1,1,1)))]) + sage: n = N.basis(); n[0].lift() + P[4, 2, 1, 1, 1, 1] + sage: n[0].degree() + 10 + sage: K = M.filtered_submodule([M(Partition((4,2,1,1,1,1))) - M(Partition((5,3)))]) + Traceback (most recent call last): + ... + ValueError: element is not homogeneous + """ + base_ring = self.base_ring() + for f in gens: + if not f.is_homogeneous(): + raise ValueError("element is not homogeneous") + return self.submodule(gens, category=FilteredModulesWithBasis(base_ring).Subobjects()) + + def filtered_quotient_module(self, submodule): + r""" + Create a graded quotient module by referencing the grading + of ``self``. The generators have to be each homogeneous. + The cokernel must be of finite dimension. + + INPUTS:: + + - ``submodule``: The generators of the submodule quotiented out. + + EXAMPLES:: + + sage: M = ModulesWithBasis(QQ).Filtered().example() + sage: N = M.filtered_submodule([M(Partition((5,3))), M(Partition((4,2,1,1,1,1)))]) + sage: n = N.basis(); n[0].lift() + P[4, 2, 1, 1, 1, 1] + sage: K = N.filtered_quotient_module([n[0]]) + sage: k = K.basis(); k + Finite family {1: B[1]} + sage: k[1].lift().lift() + P[5, 3] + sage: k[1].degree() + 8 + """ + base_ring = self.base_ring() + for f in submodule: + if not f.is_homogeneous(): + raise ValueError("element is not homogeneous") + return self.quotient_module(submodule, category=FilteredModulesWithBasis(base_ring).Quotients()) + def induced_graded_map(self, other, f): r""" Return the graded linear map between the associated graded @@ -987,4 +1047,16 @@ def truncate(self, n): return self.parent().sum_of_terms((i, c) for (i, c) in self if degree_on_basis(i) < n) + class Subobjects(SubobjectsCategory): + + class ParentMethods: + + def degree_on_basis(self, i): + return self.basis()[i].lift().degree() + + class Quotients(QuotientsCategory): + + class ParentMethods: + def degree_on_basis(self, i): + return self.basis()[i].lift().degree() diff --git a/src/sage/categories/graded_modules_with_basis.py b/src/sage/categories/graded_modules_with_basis.py index ec6f4e7590c..c5d72664820 100644 --- a/src/sage/categories/graded_modules_with_basis.py +++ b/src/sage/categories/graded_modules_with_basis.py @@ -10,7 +10,8 @@ #****************************************************************************** from sage.categories.graded_modules import GradedModulesCategory - +from sage.categories.subobjects import SubobjectsCategory +from sage.categories.quotients import QuotientsCategory class GradedModulesWithBasis(GradedModulesCategory): """ @@ -67,6 +68,64 @@ def degree_negation(self, element): for key, value in element.monomial_coefficients(copy=False).items()]) + def graded_submodule(self, gens): + r""" + Create a graded submodule by referencing the grading of + ``self``. The generators have to be each homogeneous. + + INPUTS:: + + - ``gens``: The generators of the submodule. + + EXAMPLES:: + + sage: M = ModulesWithBasis(QQ).Graded().example() + sage: N = M.graded_submodule([M(Partition((5,3))), M(Partition((4,2,1,1,1,1)))]) + sage: n = N.basis(); n[0].lift() + P[4, 2, 1, 1, 1, 1] + sage: n[0].degree() + 10 + sage: K = M.graded_submodule([M(Partition((4,2,1,1,1,1))) - M(Partition((5,3)))]) + Traceback (most recent call last): + ... + ValueError: element is not homogeneous + """ + base_ring = self.base_ring() + for f in gens: + if not f.is_homogeneous(): + raise ValueError("element is not homogeneous") + return self.submodule(gens, category=GradedModulesWithBasis(base_ring).Subobjects()) + + def graded_quotient_module(self, submodule): + r""" + Create a graded quotient module by referencing the grading + of ``self``. The generators have to be each homogeneous. + The cokernel must be of finite dimension. + + INPUTS:: + + - ``submodule``: The generators of the submodule quotiented out. + + EXAMPLES:: + + sage: M = ModulesWithBasis(QQ).Graded().example() + sage: N = M.graded_submodule([M(Partition((5,3))), M(Partition((4,2,1,1,1,1)))]) + sage: n = N.basis(); n[0].lift() + P[4, 2, 1, 1, 1, 1] + sage: K = N.graded_quotient_module([n[0]]) + sage: k = K.basis(); k + Finite family {1: B[1]} + sage: k[1].lift().lift() + P[5, 3] + sage: k[1].degree() + 8 + """ + base_ring = self.base_ring() + for f in submodule: + if not f.is_homogeneous(): + raise ValueError("element is not homogeneous") + return self.quotient_module(submodule, category=GradedModulesWithBasis(base_ring).Quotients()) + class ElementMethods: def degree_negation(self): r""" @@ -95,3 +154,16 @@ def degree_negation(self): """ return self.parent().degree_negation(self) + class Subobjects(SubobjectsCategory): + + class ParentMethods: + + def degree_on_basis(self, i): + return self.basis()[i].lift().degree() + + class Quotients(QuotientsCategory): + + class ParentMethods: + + def degree_on_basis(self, i): + return self.basis()[i].lift().degree() diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index 906f2d27581..bf4ea5bf505 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -1137,7 +1137,6 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): d = {key: coeff for key, coeff in d.items() if coeff} return self.element_class(self, d) - class CombinatorialFreeModule_Tensor(CombinatorialFreeModule): """ Tensor Product of Free Modules