Ticket #5891: categories-categories-nt.patch
| File categories-categories-nt.patch, 296.9 KB (added by nthiery, 4 years ago) |
|---|
-
setup.py
diff --git a/setup.py b/setup.py
a b code = setup(name = 'sage', 548 548 'sage.calculus', 549 549 550 550 'sage.categories', 551 'sage.categories.examples', 551 552 552 553 'sage.coding', 553 554 -
module_list.py
diff --git a/module_list.py b/module_list.py
a b ext_modules = [ 133 133 Extension('sage.categories.morphism', 134 134 sources = ['sage/categories/morphism.pyx']), 135 135 136 Extension('sage.categories.examples.semigroups_cython', 137 sources = ['sage/categories/examples/semigroups_cython.pyx']), 138 136 139 ################################ 137 140 ## 138 141 ## sage.coding -
new file sage/categories/basic.py
diff --git a/sage/categories/basic.py b/sage/categories/basic.py new file mode 100644
- + 1 r""" 2 A subset of sage.categories.all with just the basic categories needed 3 for sage startup (i.e. to define ZZ, QQ, ...). 4 """ 5 #***************************************************************************** 6 # Copyright (C) 2008 Nicolas M. Thiery <nthiery at users.sf.net> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from objects import Objects 21 from sets_cat import Sets 22 from ordered_sets import OrderedSets 23 24 from abelian_semigroups import AbelianSemigroups 25 from abelian_monoids import AbelianMonoids 26 from abelian_groups import AbelianGroups 27 28 from semigroups import Semigroups 29 from monoids import Monoids 30 from finite_semigroups import FiniteSemigroups 31 from finite_monoids import FiniteMonoids 32 from groups import Groups 33 from ordered_monoids import OrderedMonoids 34 35 from rngs import Rngs 36 from rings import Rings 37 from entire_rings import EntireRings 38 from division_rings import DivisionRings 39 40 from commutative_rings import CommutativeRings 41 from integral_domains import IntegralDomains 42 from gcd_domains import GcdDomains 43 from principal_ideal_domains import PrincipalIdealDomains 44 from euclidean_domains import EuclideanDomains 45 from unique_factorization_domains import UniqueFactorizationDomains 46 47 from fields import Fields -
sage/categories/all.py
diff --git a/sage/categories/all.py b/sage/categories/all.py
a b 1 from category import is_Category 1 from category import is_Category, Category, HomCategory, AbstractCategory 2 2 3 3 from category_types import( 4 4 Elements, 5 5 Sequences, 6 Objects,7 Sets,8 GSets,9 PointedSets,10 SetsWithPartialMaps,11 6 SimplicialComplexes, 12 Semigroups,13 Monoids,14 Groupoid,15 Groups,16 AbelianSemigroups,17 AbelianMonoids,18 AbelianGroups,19 Rings,20 CommutativeRings,21 Fields,22 FiniteFields,23 NumberFields,24 Algebras,25 CommutativeAlgebras,26 MonoidAlgebras,27 GroupAlgebras,28 MatrixAlgebras,29 RingModules,30 Modules,31 FreeModules,32 VectorSpaces,33 HeckeModules,34 RingIdeals, Ideals,35 CommutativeRingIdeals,36 AlgebraModules,37 AlgebraIdeals,38 CommutativeAlgebraIdeals,39 7 ChainComplexes, 40 Schemes, 41 ModularAbelianVarieties) 8 ) 42 9 10 from tensor import TensorialCategory, TensorCategory, tensor 11 from direct_sum import AbelianCategory, DirectSumCategory, direct_sum 12 from dual import DualityCategory 43 13 44 14 from functor import (is_Functor, 45 15 ForgetfulFunctor, … … from homset import (Hom, hom, is_Homse 51 21 52 22 from morphism import Morphism, is_Morphism 53 23 24 from basic import * 54 25 26 from g_sets import GSets 27 from pointed_sets import PointedSets 55 28 29 from sets_with_partial_maps import SetsWithPartialMaps 30 from groupoid import Groupoid 56 31 32 # enumerated sets 33 from enumerated_sets import EnumeratedSets 34 from finite_enumerated_sets import FiniteEnumeratedSets 35 from infinite_enumerated_sets import InfiniteEnumeratedSets 57 36 37 # fields 38 from quotient_fields import QuotientFields 39 from finite_fields import FiniteFields 40 from number_fields import NumberFields 41 42 # modules 43 from left_modules import LeftModules 44 from right_modules import RightModules 45 from bimodules import Bimodules 46 47 from modules import Modules 48 RingModules = Modules 49 from vector_spaces import VectorSpaces 50 51 # (hopf) algebra structures 52 from algebras import Algebras 53 from commutative_algebras import CommutativeAlgebras 54 from coalgebras import Coalgebras 55 from bialgebras import Bialgebras 56 from hopf_algebras import HopfAlgebras 57 from operads import Operads 58 59 # specific algebras 60 from monoid_algebras import MonoidAlgebras 61 from group_algebras import GroupAlgebras 62 from matrix_algebras import MatrixAlgebras 63 64 # ideals 65 from ring_ideals import RingIdeals 66 Ideals = RingIdeals 67 from commutative_ring_ideals import CommutativeRingIdeals 68 from algebra_modules import AlgebraModules 69 from algebra_ideals import AlgebraIdeals 70 from commutative_algebra_ideals import CommutativeAlgebraIdeals 71 72 # schemes and varieties 73 from modular_abelian_varieties import ModularAbelianVarieties 74 from schemes import Schemes 75 76 # * with basis 77 from modules_with_basis import ModulesWithBasis 78 FreeModules = ModulesWithBasis 79 from hecke_modules import HeckeModules 80 from algebras_with_basis import AlgebrasWithBasis 81 from coalgebras_with_basis import CoalgebrasWithBasis 82 from bialgebras_with_basis import BialgebrasWithBasis 83 from hopf_algebras_with_basis import HopfAlgebrasWithBasis 84 from operads_with_basis import OperadsWithBasis 85 86 # finite dimensional * with basis 87 from finite_dimensional_modules_with_basis import FiniteDimensionalModulesWithBasis 88 from finite_dimensional_algebras_with_basis import FiniteDimensionalAlgebrasWithBasis 89 from finite_dimensional_coalgebras_with_basis import FiniteDimensionalCoalgebrasWithBasis 90 from finite_dimensional_bialgebras_with_basis import FiniteDimensionalBialgebrasWithBasis 91 from finite_dimensional_hopf_algebras_with_basis import FiniteDimensionalHopfAlgebrasWithBasis 92 93 # graded * 94 from graded_modules import GradedModules 95 from graded_algebras import GradedAlgebras 96 from graded_coalgebras import GradedCoalgebras 97 from graded_bialgebras import GradedBialgebras 98 from graded_hopf_algebras import GradedHopfAlgebras 99 100 # graded * with basis 101 from graded_modules_with_basis import GradedModulesWithBasis 102 from graded_algebras_with_basis import GradedAlgebrasWithBasis 103 from graded_coalgebras_with_basis import GradedCoalgebrasWithBasis 104 from graded_bialgebras_with_basis import GradedBialgebrasWithBasis 105 from graded_hopf_algebras_with_basis import GradedHopfAlgebrasWithBasis 106 107 108 109 -
sage/algebras/group_algebra.py
diff --git a/sage/algebras/group_algebra.py b/sage/algebras/group_algebra.py
a b class GroupAlgebra(Algebra): 281 281 sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category() 282 282 Category of group algebras over Ring of integers modulo 12 283 283 """ 284 from sage.categories. category_typesimport GroupAlgebras284 from sage.categories.all import GroupAlgebras 285 285 return GroupAlgebras(self.base_ring()) 286 286 287 287 -
sage/algebras/steenrod_algebra.py
diff --git a/sage/algebras/steenrod_algebra.py b/sage/algebras/steenrod_algebra.py
a b class SteenrodAlgebra_generic(Algebra): 446 446 sage: A.category() 447 447 Category of algebras over Finite Field of size 3 448 448 """ 449 from sage.categories. category_typesimport Algebras449 from sage.categories.all import Algebras 450 450 return Algebras(GF(self.prime)) 451 451 452 452 -
new file sage/categories/abelian_groups.py
diff --git a/sage/categories/abelian_groups.py b/sage/categories/abelian_groups.py new file mode 100644
- + 1 r""" 2 AbelianGroups 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.category import Category 20 from sage.misc.cachefunc import cached_method 21 from sage.categories.basic import AbelianMonoids 22 23 class AbelianGroups(Category): 24 """ 25 The category of abelian groups, i.e. additive abelian monoids 26 where each element has an inverse. 27 28 EXAMPLES:: 29 30 sage: AbelianGroups() 31 Category of abelian groups 32 sage: AbelianGroups().super_categories() 33 [Category of abelian monoids] 34 sage: AbelianGroups().all_super_categories() 35 [Category of abelian groups, Category of abelian monoids, Category of abelian semigroups, Category of sets, Category of objects] 36 37 TESTS:: 38 39 sage: C = AbelianGroups() 40 sage: loads(C.dumps()) == C 41 True 42 43 """ 44 45 @cached_method 46 def super_categories(self): 47 return [AbelianMonoids()] 48 49 class ParentMethods: 50 pass 51 52 class ElementMethods: 53 ##def -x, -(x,y): 54 pass -
new file sage/categories/abelian_monoids.py
diff --git a/sage/categories/abelian_monoids.py b/sage/categories/abelian_monoids.py new file mode 100644
- + 1 r""" 2 AbelianMonoids 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.category import Category 20 from sage.misc.cachefunc import cached_method 21 from sage.categories.basic import AbelianSemigroups 22 23 # CHANGE: AbelianMonoid does not inherit any more from Monoids 24 class AbelianMonoids(Category): 25 """ 26 The category of abelian monoids 27 semigroups with an additive identity element 28 29 EXAMPLES:: 30 31 sage: AbelianMonoids() 32 Category of abelian monoids 33 sage: AbelianMonoids().super_categories() 34 [Category of abelian semigroups] 35 sage: AbelianMonoids().all_super_categories() 36 [Category of abelian monoids, Category of abelian semigroups, Category of sets, Category of objects] 37 38 TESTS:: 39 40 sage: C = AbelianMonoids() 41 sage: loads(C.dumps()) == C 42 True 43 44 """ 45 46 @cached_method 47 def super_categories(self): 48 return [AbelianSemigroups()] 49 50 class ParentMethods: 51 52 @cached_method 53 def zero(self): 54 """ 55 Returns the zero of the abelian monoid, that is the unique neutral element for `+`. 56 57 The default implementation is to coerce 0 into self. 58 59 It is recommended to override this method because the 60 coercion from the integers: 61 - is not always meaningful (except for `0`), 62 - often uses self.zero() otherwise. 63 """ 64 return self(0) 65 66 def zero_element(self): 67 """ 68 Alias for self.zero(), for backward compatibility 69 """ 70 return self.zero() 71 72 class ElementMethods: 73 def __sub__(left, right): 74 """ 75 Top-level subtraction operator for ModuleElements. 76 See extensive documentation at the top of element.pyx. 77 """ 78 if left.parent() == right.parent() and hasattr(left, "_sub_"): 79 return left._sub_(right) 80 from sage.structure.element import get_coercion_model 81 import operator 82 return get_coercion_model().bin_op(left, right, operator.sub) 83 84 ################################################## 85 # Negation 86 ################################################## 87 88 def __neg__(self): 89 """ 90 Top-level negation operator for elements of abelian 91 monoids, which may choose to implement _neg_ rather than 92 __neg__ for consistancy. 93 """ 94 return self._neg_() -
new file sage/categories/abelian_semigroups.py
diff --git a/sage/categories/abelian_semigroups.py b/sage/categories/abelian_semigroups.py new file mode 100644
- + 1 r""" 2 AbelianSemigroups 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.misc.abstract_method import abstract_method 20 from sage.misc.cachefunc import cached_method 21 from sage.misc.lazy_attribute import lazy_attribute 22 from sage.categories.category import Category 23 from sage.categories.sets_cat import Sets 24 from sage.structure.sage_object import have_same_parent 25 26 class AbelianSemigroups(Category): 27 """ 28 The category of additive abelian semigroups, i.e. sets with an 29 associative and abelian operation +. 30 31 EXAMPLES:: 32 33 sage: AbelianSemigroups() 34 Category of abelian semigroups 35 sage: AbelianSemigroups().super_categories() 36 [Category of sets] 37 sage: AbelianSemigroups().all_super_categories() 38 [Category of abelian semigroups, Category of sets, Category of objects] 39 40 TESTS:: 41 sage: C = AbelianSemigroups() 42 sage: loads(C.dumps()) == C 43 True 44 45 """ 46 47 @cached_method 48 def super_categories(self): 49 return [Sets()] 50 51 class ParentMethods: 52 def test_additive_associativity(self, **options): 53 tester = self.tester(**options) 54 # Better than use all. 55 for x in tester.some_elements(): 56 for y in tester.some_elements(): 57 for z in tester.some_elements(): 58 tester.assert_((x + y) + z == x + (y + z)) 59 60 @abstract_method 61 def summation(self, x, y): 62 """ 63 The binary addition operator of the semigroup 64 65 This must be implemented by any parent in AdditiveSemigroups(). 66 67 INPUT: 68 - ``x``, ``y``: elements of this additive semigroup 69 70 Returns the product of ``x`` and ``y`` 71 72 EXAMPLES:: 73 74 sage: S = AdditiveSemigroups().example() # todo: not implemented 75 sage: x = S('a'); y = S('b') # todo: not implemented 76 sage: S.summation(x, y) # todo: not implemented 77 'ab' 78 79 By default, the addition method on elements 80 ``x._add_(y)`` calls ``S.product(x,y)`` (not yet implemented). 81 82 As a bonus effect, ``S.product`` by itself models the 83 binary function from ``S`` to ``S``:: 84 85 sage: bin = S.summation # todo: not implemented 86 sage: bin(x,y) # todo: not implemented 87 'ab' 88 89 Here, ``S.product`` is just a bound method. Whenever 90 possible, it is recommended to enrich this ``S.product`` 91 with extra mathematical structure. Lazy attributes can 92 come handy for this. 93 94 Todo: add an example. 95 """ 96 pass 97 98 class ElementMethods: 99 100 def _add_parent(self, other): 101 return self.parent().summation(self, other) 102 103 def __add__(left, right): 104 if have_same_parent(left, right) and hasattr(left, "_add_"): 105 return left._add_(right) 106 from sage.structure.element import get_coercion_model 107 import operator 108 return get_coercion_model().bin_op(left, right, operator.add) 109 110 def __radd__(right, left): 111 if have_same_parent(left, right) and hasattr(left, "_add_"): 112 return left._add_(right) 113 from sage.structure.element import get_coercion_model 114 import operator 115 return get_coercion_model().bin_op(left, right, operator.add) 116 -
new file sage/categories/algebra_ideals.py
diff --git a/sage/categories/algebra_ideals.py b/sage/categories/algebra_ideals.py new file mode 100644
- + 1 r""" 2 AlgebraIdeals 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from sage.misc.cachefunc import cached_method 22 from category_types import Category_ideal 23 24 class AlgebraIdeals(Category_ideal): 25 """ 26 The category of ideals in a fixed algebra $A$. 27 28 EXAMPLES: 29 sage: C = AlgebraIdeals(FreeAlgebra(QQ,2,'a,b')) 30 sage: loads(C.dumps()) == C 31 True 32 """ 33 def __init__(self, A): 34 from sage.algebras.algebra import is_Algebra 35 if not is_Algebra(A): # A not in Algebras() ? 36 raise TypeError, "A (=%s) must be an algebra"%A 37 Category_ideal.__init__(self, A) 38 39 def algebra(self): 40 return self.ambient() 41 42 @cached_method 43 def super_categories(self): 44 from algebra_modules import AlgebraModules 45 R = self.algebra() 46 return [AlgebraModules(R)] -
new file sage/categories/algebra_modules.py
diff --git a/sage/categories/algebra_modules.py b/sage/categories/algebra_modules.py new file mode 100644
- + 1 r""" 2 AlgebraModules 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from sage.misc.cachefunc import cached_method 22 from category_types import Category_module 23 24 class AlgebraModules(Category_module): 25 """ 26 The category of modules over a fixed algebra $A$. 27 28 TESTS: 29 sage: C = AlgebraModules(FreeAlgebra(QQ,2,'a,b')) 30 sage: loads(C.dumps()) == C 31 True 32 """ 33 def __init__(self, A): 34 from sage.algebras.algebra import is_Algebra 35 if not is_Algebra(A): # A not in Algebras()? 36 raise TypeError, "A (=%s) must be an algebra"%A 37 Category_module.__init__(self, A) 38 39 def algebra(self): 40 return self.base_ring() 41 42 @cached_method 43 def super_categories(self): 44 R = self.algebra() 45 from modules import Modules 46 return [Modules(R)] -
new file sage/categories/algebras.py
diff --git a/sage/categories/algebras.py b/sage/categories/algebras.py new file mode 100644
- + 1 r""" 2 Algebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import Hom, Rings, Modules, Semigroups, AbelianCategory, DirectSumCategory, direct_sum 21 from sage.categories.morphism import SetMorphism 22 from sage.misc.cachefunc import cached_method 23 from sage.misc.lazy_attribute import lazy_attribute 24 from sage.structure.element import AlgebraElement, get_coercion_model 25 from sage.structure.sage_object import have_same_parent 26 from sage.rings.integer import Integer 27 import operator 28 29 class Algebras(Category_over_base_ring, AbelianCategory): 30 """ 31 The category of algebras over a given base ring. 32 33 An algebra over a ring R is a module over R which is itself a ring. 34 35 TODO: should R be a commutative ring? 36 37 EXAMPLES: 38 sage: Algebras(ZZ) 39 Category of algebras over Integer Ring 40 sage: Algebras(ZZ).super_categories() 41 [Category of rings, Category of modules over Integer Ring] 42 43 TESTS: 44 sage: C = Algebras(ZZ) 45 sage: loads(dumps(C)) == C 46 True 47 48 """ 49 50 # For backward compatibility? 51 def __contains__(self, x): 52 from sage.structure.parent import Parent 53 from ring import Algebra 54 return (isinstance(x, Parent) and x.category()) or (isinstance(x, Algebra) and x.base_ring() == self.base_field()) 55 56 def base_field(self): 57 """ 58 Return the base field over which the algebras of this category 59 are all defined. 60 """ 61 return self.base_ring() 62 63 @cached_method 64 def super_categories(self): 65 R = self.base_ring() 66 return [Rings(), Modules(R)] 67 68 class ParentMethods: # (Algebra): # Eventually, the content of Algebra should be moved here 69 def from_base_ring(self, r): 70 return self.one()._lmul_(r) 71 72 def __init_extra__(self): 73 # TODO: find and implement a good syntax! 74 self.register_coercion(SetMorphism(function = self.from_base_ring, parent = Hom(self.base_ring(), self, Rings()))) 75 # Should be a morphism of Algebras(self.base_ring()), but e.g. QQ is not in Algebras(QQ) 76 77 class ElementMethods: 78 # TODO: move the content of AlgebraElement here 79 80 # Workaround: this sets back Semigroups.Element.__mul__, which is currently overriden by Modules.Element.__mul__ 81 # What does this mean in terms of inheritance order? 82 # Could we do a variant like __mul__ = Semigroups.Element.__mul__ 83 def __mul__(self, right): 84 """ 85 EXAMPLES:: 86 sage: s = SFASchur(QQ) 87 sage: a = s([2]) 88 sage: a._mul_(a) #indirect doctest 89 s[2, 2] + s[3, 1] + s[4] 90 91 Todo: use AlgebrasWithBasis(QQ).example() 92 """ 93 if have_same_parent(self, right) and hasattr(self, "_mul_"): 94 return self._mul_(right) 95 from sage.structure.element import get_coercion_model 96 import operator 97 return get_coercion_model().bin_op(self, right, operator.mul) 98 99 # __imul__ = __mul__ 100 101 # Parents in this category should implement _lmul_ and _rmul_ 102 103 def _div_(self, y): 104 """ 105 # TODO: move in Monoids 106 107 EXAMPLES: 108 sage: C = AlgebrasWithBasis(QQ).example() 109 sage: x = C(2); x 110 2*B[()] 111 sage: y = C.algebra_generators().first(); y 112 B[(1,2,3)] 113 114 sage: y._div_(x) 115 1/2*B[(1,2,3)] 116 sage: x._div_(y) 117 Traceback (most recent call last): 118 ... 119 ValueError: cannot invert self (= B[(1,2,3)]) 120 """ 121 return self.parent().product(self, ~y) 122 123 class DirectSumCategory(DirectSumCategory): 124 """ 125 The category of modules with basis constructed by direct sums of modules with basis 126 """ 127 @cached_method 128 def super_categories(self): 129 return [Algebras(self.base_category.base_ring())] 130 131 class ParentMethods: 132 @cached_method 133 def one(self): 134 """ 135 EXAMPLES: 136 sage: S = direct_sum([SymmetricGroupAlgebra(QQ, 3), SymmetricGroupAlgebra(QQ, 4)]) 137 sage: S.one() 138 B[(0, [1, 2, 3])] + B[(1, [1, 2, 3, 4])] 139 """ 140 return direct_sum([module.one() for module in self.modules]) 141 142 def product(self, left, right): 143 """ 144 EXAMPLES: 145 sage: A = SymmetricGroupAlgebra(QQ, 3); 146 sage: x = direct_sum([A([1,3,2]), A([2,3,1])]) 147 sage: y = direct_sum([A([1,3,2]), A([2,3,1])]) 148 sage: direct_sum([A,A]).product(x,y) 149 B[(0, [1, 2, 3])] + B[(1, [3, 1, 2])] 150 sage: x*y 151 B[(0, [1, 2, 3])] + B[(1, [3, 1, 2])] 152 """ 153 154 return direct_sum([(a*b) for (a,b) in zip(left.summand_split(), right.summand_split())]) -
new file sage/categories/algebras_with_basis.py
diff --git a/sage/categories/algebras_with_basis.py b/sage/categories/algebras_with_basis.py new file mode 100644
- + 1 r""" 2 AlgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Nicolas Thiery 6 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from sage.misc.abstract_method import abstract_method 21 from sage.misc.cachefunc import cached_method 22 from sage.misc.lazy_attribute import lazy_attribute 23 from sage.categories.all import Category, TensorialCategory, TensorCategory, AbelianCategory, DirectSumCategory, tensor, DualityCategory, ModulesWithBasis, Algebras 24 from category_types import Category_over_base_ring 25 26 class AlgebrasWithBasis(Category_over_base_ring, AbelianCategory, TensorialCategory, DualityCategory): 27 """ 28 The category of algebras with a distinguished basis 29 30 EXAMPLES:: 31 32 sage: C = AlgebrasWithBasis(QQ); C 33 Category of algebras with basis over Rational Field 34 sage: C.super_categories() 35 [Category of modules with basis over Rational Field, Category of algebras over Rational Field] 36 37 We construct a typical parent in this category, and do some computations with it:: 38 39 sage: A = C.example(); A 40 The group algebra of Dihedral group of order 6 as a permutation group over Rational Field 41 42 sage: A.category() 43 Category of algebras with basis over Rational Field 44 45 sage: A.one_basis() 46 () 47 sage: A.one() 48 B[()] 49 50 sage: A.base_ring() 51 Rational Field 52 sage: A.basis().keys() 53 Dihedral group of order 6 as a permutation group 54 55 sage: [a,b] = A.algebra_generators() 56 sage: a, b 57 (B[(1,2,3)], B[(1,3)]) 58 sage: a^3, b^2 59 (B[()], B[()]) 60 sage: a*b 61 B[(1,2)] 62 63 sage: A.product 64 Generic endomorphism of The group algebra of Dihedral group of order 6 as a permutation group over Rational Field 65 sage: A.product(b,b) 66 B[()] 67 68 sage: A.check(verbose=True) 69 running test_additive_associativity ... done 70 running test_an_element ... done 71 running test_associativity ... done 72 running test_element_pickling ... done 73 running test_not_implemented_methods ... done 74 running test_one ... done 75 running test_pickling ... done 76 running test_prod ... done 77 running test_product ... done 78 running test_some_elements ... done 79 sage: A.__class__ 80 <class 'sage.categories.examples.algebras_with_basis.MyGroupAlgebra_with_category'> 81 sage: A.element_class 82 <class 'sage.combinat.free_module.MyGroupAlgebra_with_category.element_class'> 83 84 Please see the source code of `A` (with ``A??``) for how to 85 implement other algebras with basis. 86 87 """ 88 89 @cached_method 90 def super_categories(self): 91 R = self.base_ring() 92 return [ModulesWithBasis(R), Algebras(R)] 93 94 def example(self, G = None): 95 """ 96 Returns an example of algebra with basis:: 97 98 sage: AlgebrasWithBasis(QQ).example() 99 The group algebra of Dihedral group of order 6 as a permutation group over Rational Field 100 101 An other group can be specified as optional argument:: 102 103 sage: AlgebrasWithBasis(QQ).example(SymmetricGroup(4)) 104 The group algebra of SymmetricGroup(4) over Rational Field 105 106 """ 107 from sage.categories.examples.algebras_with_basis import MyGroupAlgebra 108 from sage.groups.perm_gps.permgroup_named import DihedralGroup 109 if G is None: 110 G = DihedralGroup(3) 111 return MyGroupAlgebra(self.base_ring(), G) 112 113 class ParentMethods: 114 115 #@cached_method # todo: reinstate once #5843 is fixed 116 def one_from_one_basis(self): 117 return self.term(self.one_basis()) 118 119 @lazy_attribute 120 def one(self): 121 if hasattr(self, "one_basis"): 122 return self.one_from_one_basis 123 else: 124 return NotImplemented 125 126 @lazy_attribute 127 def from_base_ring(self): 128 if hasattr(self, "one_basis"): 129 return self.from_base_ring_from_one_basis 130 else: 131 return NotImplemented 132 133 def from_base_ring_from_one_basis(self, r): 134 """ 135 INPUTS: 136 137 - `r`: an element of the coefficient ring 138 139 Implements the canonical embeding from the ground ring. 140 141 EXAMPLES:: 142 143 sage: A = AlgebrasWithBasis(QQ).example() 144 sage: A.from_base_ring_from_one_basis(3) 145 3*B[()] 146 sage: A.from_base_ring(3) 147 3*B[()] 148 sage: A(3) 149 3*B[()] 150 151 """ 152 return self.monomial(self.one_basis(), r) 153 154 def test_one(self, **options): 155 tester = self.tester(**options) 156 tester.assert_(self.one() in self) 157 tester.assert_(all(self.one() * x == x for x in self.basis())) 158 159 @abstract_method("optional") 160 def product_on_basis(self, i, j): 161 """ 162 The product of the algebra on the basis (optional) 163 164 INPUT: 165 - ``i``, ``j``: the indices of two elements of the basis of self 166 167 Returns the product of the two corresponding basis elements 168 169 If implemented, :met:`product` is defined from it by bilinearity. 170 171 EXAMPLES:: 172 173 sage: A = AlgebrasWithBasis(QQ).example() 174 sage: i, j = A.algebra_generators().keys() 175 sage: i, j 176 ((1,2,3), (1,3)) 177 sage: A.product_on_basis(i,j) 178 B[(1,2)] 179 """ 180 181 @lazy_attribute 182 def product(self): 183 """ 184 The product of the algebra, as per ``Algebras.ParentMethods.product`` 185 186 By default, this is implemented from 187 :meth:`product_on_basis`, if available. 188 189 EXAMPLES:: 190 191 sage: A = AlgebrasWithBasis(QQ).example() 192 sage: x, y = A.algebra_generators() 193 sage: A.product(x + 2*y, 3*y) 194 6*B[()] + 3*B[(1,2)] 195 196 """ 197 if self.product_on_basis is not NotImplemented: 198 return self._module_morphism(self._module_morphism(self.product_on_basis, position = 0, codomain=self), 199 position = 1) 200 elif hasattr(self, "_multiply") or hasattr(self, "_multiply_basis"): 201 return self._product_from_combinatorial_algebra_multiply 202 else: 203 return NotImplemented 204 205 # Backward compatibility temporary cruft to help migrating form CombinatorialAlgebra 206 def _product_from_combinatorial_algebra_multiply(self,left,right): 207 """ 208 Returns left\*right where left and right are elements of self. 209 product() uses either _multiply or _multiply basis to carry out 210 the actual multiplication. 211 212 EXAMPLES:: 213 214 sage: s = SFASchur(QQ) 215 sage: a = s([2]) 216 sage: s.product(a,a) 217 s[2, 2] + s[3, 1] + s[4] 218 """ 219 A = left.parent() 220 BR = A.base_ring() 221 z_elt = {} 222 223 #Do the case where the user specifies how to multiply basis elements 224 if hasattr(self, '_multiply_basis'): 225 for (left_m, left_c) in left._monomial_coefficients.iteritems(): 226 for (right_m, right_c) in right._monomial_coefficients.iteritems(): 227 res = self._multiply_basis(left_m, right_m) 228 #Handle the case where the user returns a dictionary 229 #where the keys are the monomials and the values are 230 #the coefficients. If res is not a dictionary, then 231 #it is assumed to be an element of self 232 if not isinstance(res, dict): 233 if isinstance(res, self._element_class): 234 res = res._monomial_coefficients 235 else: 236 res = {res: BR(1)} 237 for m in res: 238 if m in z_elt: 239 z_elt[ m ] = z_elt[m] + left_c * right_c * res[m] 240 else: 241 z_elt[ m ] = left_c * right_c * res[m] 242 243 #We assume that the user handles the multiplication correctly on 244 #his or her own, and returns a dict with monomials as keys and 245 #coefficients as values 246 else: 247 m = self._multiply(left, right) 248 if isinstance(m, self._element_class): 249 return m 250 if not isinstance(m, dict): 251 z_elt = m.monomial_coefficients() 252 else: 253 z_elt = m 254 255 #Remove all entries that are equal to 0 256 BR = self.base_ring() 257 zero = BR(0) 258 del_list = [] 259 for m, c in z_elt.iteritems(): 260 if c == zero: 261 del_list.append(m) 262 for m in del_list: 263 del z_elt[m] 264 265 return self._from_dict(z_elt) 266 267 268 269 def test_product(self, **options): 270 tester = self.tester(**options) 271 tester.assert_(self.product is not None) 272 # could check that self.product is in Hom( self x self, self) 273 274 class ElementMethods: 275 276 def __invert__(self): 277 """ 278 Returns the inverse of self if self is a multiple of one, 279 and one is in the basis of this algebra. Otherwise throws 280 an error. 281 282 Caveat: this generic implementation is not complete; there 283 may be invertible elements in the algebra that can't be 284 inversed this way. It is correct though for graded 285 connected algebras with basis. 286 287 EXAMPLES: 288 sage: C = AlgebrasWithBasis(QQ).example() 289 sage: x = C(2); x 290 2*B[()] 291 sage: ~x 292 1/2*B[()] 293 sage: x = C.algebra_generators().first(); x 294 B[(1,2,3)] 295 sage: ~x 296 Traceback (most recent call last): 297 ... 298 ValueError: cannot invert self (= B[(1,2,3)]) 299 """ 300 # FIXME: make this generic 301 mcs = self._monomial_coefficients 302 one = self.parent().one_basis() 303 if len(mcs) == 1 and one in mcs: 304 return self.parent()( ~mcs[ one ] ) 305 else: 306 raise ValueError, "cannot invert self (= %s)"%self 307 308 309 class DirectSumCategory(DirectSumCategory): 310 """ 311 The category of algebras with basis constructed by direct sums of algebras with basis 312 """ 313 314 @cached_method 315 def super_categories(self): 316 return [AlgebrasWithBasis(self.base_category.base_ring())] 317 318 class ParentMethods: 319 #@cached_method # todo: reinstate once #5843 is fixed 320 def one_from_direct_sum_of_one_basis(self): 321 # This implementation does not require multiplication by 322 # scalars nor calling direct_sum. This might help keeping 323 # things as lazy as possible upon initialization 324 return self.sum_of_terms( (i, self.modules[i].one_basis()) for i in range(len(self.modules))) 325 326 @lazy_attribute 327 def one(self): 328 if all(hasattr(module, "one_basis") for module in self.modules): 329 return self.one_from_direct_sum_of_one_basis 330 else: 331 return NotImplemented 332 333 #def product_on_basis(self, t1, t2): 334 # would be easy to implement, but without a special 335 # version of module morphism, this would not take 336 # advantage of the bloc structure 337 338 339 class TensorCategory(TensorCategory): 340 """ 341 The category of algebras with basis constructed by tensor product of algebras with basis 342 """ 343 344 @cached_method 345 def super_categories(self): 346 return [AlgebrasWithBasis(self.base_category.base_ring())] 347 348 class ParentMethods: 349 """ 350 implements operations on tensor products of algebras with basis 351 """ 352 353 @cached_method 354 def one_basis(self): 355 if all(hasattr(module, "one_basis") for module in self.modules): 356 return tuple(module.one_basis() for module in self.modules) 357 358 def product_on_basis(self, t1, t2): 359 # TODO: optimize! 360 return tensor( (module.term(x1)*module.term(x2) for (module, x1, x2) in zip(self.modules, t1, t2)) ) 361 362 class ElementMethods: 363 """ 364 implements operations on elements of tensor products of algebras with basis 365 """ 366 pass -
new file sage/categories/bialgebras.py
diff --git a/sage/categories/bialgebras.py b/sage/categories/bialgebras.py new file mode 100644
- + 1 r""" 2 Bialgebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Nicolas Thiery 6 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from sage.misc.cachefunc import cached_method 21 from sage.misc.lazy_attribute import lazy_attribute 22 from sage.categories.category_types import Category_over_base_ring 23 from sage.categories.all import Algebras, Coalgebras 24 25 class Bialgebras(Category_over_base_ring): 26 """ 27 The category of bialgebras 28 29 EXAMPLES: 30 sage: Bialgebras(ZZ) 31 Category of bialgebras over Integer Ring 32 sage: Bialgebras(ZZ).super_categories() 33 [Category of algebras over Integer Ring, Category of coalgebras over Integer Ring] 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [Algebras(R), Coalgebras(R)] 40 41 class ParentMethods: 42 @lazy_attribute 43 def antipode(self, existence_only): 44 if self.implements("antipode_basis"): 45 if existence_only: 46 return True 47 else: 48 return self.module_morphism(self.antipode_basis) 49 50 class ElementMethods: 51 pass -
new file sage/categories/bialgebras_with_basis.py
diff --git a/sage/categories/bialgebras_with_basis.py b/sage/categories/bialgebras_with_basis.py new file mode 100644
- + 1 r""" 2 BialgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Nicolas Thiery 6 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from sage.misc.cachefunc import cached_method 21 from sage.misc.lazy_attribute import lazy_attribute 22 from category_types import Category_over_base_ring 23 from sage.categories.all import AlgebrasWithBasis, CoalgebrasWithBasis, Bialgebras 24 25 class BialgebrasWithBasis(Category_over_base_ring): 26 """ 27 The category of bialgebras with a distinguished basis 28 29 EXAMPLES:: 30 31 sage: BialgebrasWithBasis(ZZ) 32 Category of bialgebras with basis over Integer Ring 33 sage: BialgebrasWithBasis(ZZ).super_categories() 34 [Category of algebras with basis over Integer Ring, Category of coalgebras with basis over Integer Ring, Category of bialgebras over Integer Ring] 35 36 """ 37 38 @cached_method 39 def super_categories(self): 40 R = self.base_ring() 41 return [AlgebrasWithBasis(R), CoalgebrasWithBasis(R), Bialgebras(R)] 42 43 class ParentMethods: 44 @lazy_attribute 45 def antipode(self, existence_only): 46 if self.implements("antipode_basis"): 47 if existence_only: 48 return True 49 else: 50 return self.module_morphism(self.antipode_basis) 51 52 class ElementMethods: 53 pass -
new file sage/categories/bimodules.py
diff --git a/sage/categories/bimodules.py b/sage/categories/bimodules.py new file mode 100644
- + 1 r""" 2 Bimodules 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.all import Category, LeftModules, RightModules 20 from sage.categories.category import Category 21 from sage.misc.cachefunc import cached_method 22 23 #?class Bimodules(Category_over_base_rng, Category_over_base_rng): 24 class Bimodules(Category): 25 """ 26 The category of (R,S)-bimodules 27 28 A (R,S)-bimodule is a left R-module and right S-module such that 29 the left and right actions commute: $r*(x*s) = (r*x)*s$ 30 31 EXAMPLES: 32 sage: Bimodules(QQ, ZZ) 33 Category of bimodules over Rational Field on the left and Integer Ring on the right 34 sage: Bimodules(QQ, ZZ).super_categories() 35 [Category of left modules over Rational Field, Category of right modules over Integer Ring] 36 37 """ 38 39 def __init__(self, left_base, right_base, name=None): 40 Category.__init__(self, name) 41 self.__left_base_ring = left_base 42 self.__right_base_ring = right_base 43 44 def _repr_(self): 45 return Category._repr_(self) + " over %s on the left and %s on the right" \ 46 %(self.__left_base_ring, self.__right_base_ring) 47 48 def left_base_ring(self): 49 """ 50 Return the left base ring over which elements of this category are 51 defined. 52 """ 53 return self.__left_base_ring 54 55 def right_base_ring(self): 56 """ 57 Return the right base ring over which elements of this category are 58 defined. 59 """ 60 return self.__right_base_ring 61 62 def _latex_(self): 63 return "\\mbox{\\bf %s}_{%s}_{%s}"%(self.__label, latex(self.__left_base_ring), latex(self.__right_base_ring)) 64 65 @cached_method 66 def super_categories(self): 67 R = self.left_base_ring() 68 S = self.right_base_ring() 69 return [LeftModules(R), RightModules(S)] 70 71 class ParentMethods: 72 pass 73 74 class ElementMethods: 75 pass -
new file sage/categories/coalgebras.py
diff --git a/sage/categories/coalgebras.py b/sage/categories/coalgebras.py new file mode 100644
- + 1 from category_types import Category_over_base_ring 2 from sage.categories.all import Modules, Algebras, TensorialCategory, TensorCategory, DualityCategory, tensor 3 from sage.misc.lazy_attribute import lazy_attribute 4 from sage.misc.cachefunc import cached_method 5 6 class Coalgebras(Category_over_base_ring, TensorialCategory, DualityCategory): 7 """ 8 The category of coalgebras 9 10 EXAMPLES:: 11 12 sage: Coalgebras(QQ) 13 Category of coalgebras over Rational Field 14 sage: Coalgebras(QQ).super_categories() 15 [Category of modules over Rational Field] 16 sage: Coalgebras(QQ).all_super_categories() # todo: update once the hierarchy is more appropriate 17 [Category of coalgebras over Rational Field, 18 Category of modules over Rational Field, 19 Category of bimodules over Rational Field on the left and Rational Field on the right, 20 Category of left modules over Rational Field, 21 Category of right modules over Rational Field, 22 Category of abelian groups, 23 Category of abelian monoids, 24 Category of abelian semigroups, 25 Category of sets, 26 Category of objects] 27 """ 28 @cached_method 29 def super_categories(self): 30 return [Modules(self.base_ring())] 31 32 def dual(self): 33 """ 34 Returns the dual category 35 36 EXAMPLES: 37 The category of coalgebras over the Rational Field is dual 38 to the category of algebras over the same field: 39 40 sage: C = Coalgebras(QQ) 41 sage: C.dual() 42 Category of algebras over Rational Field 43 """ 44 return Algebras(self.base_ring()) 45 46 class ParentMethods: 47 def __init_add__(self): # The analogue of initDomainAdd 48 # If it exists, declare the coproduct of self to the coercion mechanism 49 pass 50 51 # TODO: attribute/method? caching just rely on the caching of Tensor? 52 @lazy_attribute 53 def tensor_square(self): 54 return tensor([self, self]) 55 56 # CHECKME 57 def coproduct(self, x): 58 """ 59 Returns the coproduct of x 60 61 The default implementation is to delegate to the 62 overloading mechanism and force the conversion back 63 """ 64 return self.tensor_square(overloaded_coproduct(x)) 65 66 class ElementMethods: 67 def coproduct(self): 68 """ 69 Returns the coproduct of self 70 """ 71 return self.parent().coproduct(self) 72 73 class TensorCategory(TensorCategory): 74 @cached_method 75 def super_categories(self): 76 return [Coalgebras(self.base_category.base_ring())] 77 78 class ParentMethods: 79 def coproduct(self): 80 # Not tested yet! 81 return tensor(module.coproduct for module in self.modules) 82 83 class ElementMethods: 84 " implements operations on elements of tensor products of coalgebras" 85 pass -
new file sage/categories/coalgebras_with_basis.py
diff --git a/sage/categories/coalgebras_with_basis.py b/sage/categories/coalgebras_with_basis.py new file mode 100644
- + 1 r""" 2 CoalgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Nicolas Thiery 6 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from sage.misc.abstract_method import abstract_method 21 from sage.misc.cachefunc import cached_method 22 from sage.misc.lazy_attribute import lazy_attribute 23 from category_types import Category_over_base_ring 24 from sage.categories.all import Coalgebras, ModulesWithBasis, tensor, Hom 25 #from sage.categories.homset import Hom 26 27 class CoalgebrasWithBasis(Category_over_base_ring): 28 """ 29 The category of coalgebras with a distinguished basis 30 31 EXAMPLES: 32 sage: CoalgebrasWithBasis(ZZ) 33 Category of coalgebras with basis over Integer Ring 34 sage: CoalgebrasWithBasis(ZZ).super_categories() 35 [Category of modules with basis over Integer Ring, Category of coalgebras over Integer Ring] 36 37 """ 38 39 @cached_method 40 def super_categories(self): 41 R = self.base_ring() 42 return [ModulesWithBasis(R), Coalgebras(R)] 43 44 class ParentMethods: 45 46 @abstract_method("optional") 47 def coproduct_on_basis(self, i): 48 """ 49 The product of the algebra on the basis (optional) 50 51 INPUT: 52 - ``i``: the indices of an element of the basis of self 53 54 Returns the coproduct of the corresponding basis elements 55 If implemented, the coproduct of the algebra is defined 56 from it by linearity. 57 """ 58 59 class ParentMethods: 60 @lazy_attribute 61 def coproduct(self): 62 if self.coproduct_on_basis is not NotImplemented: 63 # TODO: if self is a coalgebra, then one would want 64 # to create a morphism of algebras with basis instead 65 # should there be a method self.coproduct_hom_category? 66 return Hom(self, tensor([self, self]), ModulesWithBasis(self.base_ring()))(on_basis = self.coproduct_on_basis) 67 68 class ElementMethods: 69 pass -
new file sage/categories/commutative_algebra_ideals.py
diff --git a/sage/categories/commutative_algebra_ideals.py b/sage/categories/commutative_algebra_ideals.py new file mode 100644
- + 1 r""" 2 CommutativeAlgebraIdeals 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from sage.misc.cachefunc import cached_method 22 from category_types import Category_ideal 23 24 class CommutativeAlgebraIdeals(Category_ideal): 25 """ 26 The category of ideals in a fixed commutative algebra $A$. 27 """ 28 def __init__(self, A): 29 if not is_CommutativeAlgebra(A): 30 raise TypeError, "A (=%s) must be a commutative algebra"%A 31 Category_in_ambient.__init__(self, A) 32 33 def algebra(self): 34 return self.ambient() 35 36 @cached_method 37 def super_categories(self): 38 from algebra_ideals import AlgebraIdeals 39 R = self.algebra() 40 return [AlgebraIdeals(R)] -
new file sage/categories/commutative_algebras.py
diff --git a/sage/categories/commutative_algebras.py b/sage/categories/commutative_algebras.py new file mode 100644
- + 1 r""" 2 MonoidAlgebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from sage.misc.cachefunc import cached_method 22 from category_types import Category_over_base_ring 23 24 class CommutativeAlgebras(Category_over_base_ring): 25 """ 26 The category of commutative algebras over a given base ring. 27 28 EXAMPLES: 29 sage: M = CommutativeAlgebras(GF(19)) 30 sage: M 31 Category of commutative algebras over Finite Field of size 19 32 33 TESTS: 34 sage: C = CommutativeAlgebras(ZZ) 35 sage: loads(C.dumps()) == C 36 True 37 """ 38 39 @cached_method 40 def super_categories(self): 41 from algebras import Algebras 42 R = self.base_ring() 43 return [Algebras(R)] -
new file sage/categories/commutative_ring_ideals.py
diff --git a/sage/categories/commutative_ring_ideals.py b/sage/categories/commutative_ring_ideals.py new file mode 100644
- + 1 r""" 2 CommutativeRingIdeals 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from sage.misc.cachefunc import cached_method 22 from category_types import Category_ideal 23 24 class CommutativeRingIdeals(Category_ideal): 25 """ 26 The category of ideals in a fixed commutative ring. 27 28 EXAMPLES: 29 30 sage: C = CommutativeRingIdeals(IntegerRing()) 31 sage: C 32 Category of commutative ring ideals in Integer Ring 33 34 TESTS: 35 sage: C = CommutativeRingIdeals(ZZ) 36 sage: loads(C.dumps()) == C 37 True 38 """ 39 def __init__(self, R): 40 import sage.rings.all 41 if not sage.rings.all.is_CommutativeRing(R): 42 raise TypeError, "R (=%s) must be a commutative ring"%R 43 Category_ideal.__init__(self, R) 44 45 @cached_method 46 def super_categories(self): 47 from ring_ideals import RingIdeals 48 R = self.ring() 49 return [RingIdeals(R)] -
new file sage/categories/commutative_rings.py
diff --git a/sage/categories/commutative_rings.py b/sage/categories/commutative_rings.py new file mode 100644
- + 1 r""" 2 CommutativeRings 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.category import Category 20 from sage.misc.cachefunc import cached_method 21 22 class CommutativeRings(Category): 23 """ 24 The category of commutative rings 25 26 commutative rings with unity, i.e. rings with commutative * and 27 a multiplicative identity 28 29 EXAMPLES: 30 sage: CommutativeRings() 31 Category of commutative rings 32 sage: CommutativeRings().super_categories() 33 [Category of rings] 34 35 TESTS: 36 sage: C = CommutativeRings() 37 sage: loads(C.dumps()) == C 38 True 39 """ 40 41 @cached_method 42 def super_categories(self): 43 from sage.categories.rings import Rings 44 return [Rings()] # TODO: Bimodule(R,R) 45 46 class ParentMethods: 47 pass 48 49 class ElementMethods: 50 pass -
new file sage/categories/division_rings.py
diff --git a/sage/categories/division_rings.py b/sage/categories/division_rings.py new file mode 100644
- + 1 r""" 2 DivisionRings 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.category import Category 20 from sage.misc.cachefunc import cached_method 21 22 class DivisionRings(Category): 23 """ 24 The category of division rings 25 26 a division ring (or skew field) is a not necessarily commutative 27 ring where all non-zero elements have multiplicative inverses 28 29 EXAMPLES: 30 sage: DivisionRings() 31 Category of division rings 32 sage: DivisionRings().super_categories() 33 [Category of entire rings] 34 35 """ 36 37 @cached_method 38 def super_categories(self): 39 from sage.categories.entire_rings import EntireRings 40 return [EntireRings()] # TODO: Algebra(QQ) sounds wrong (think Z/Z2) 41 42 class ParentMethods: 43 pass 44 45 class ElementMethods: 46 pass -
new file sage/categories/entire_rings.py
diff --git a/sage/categories/entire_rings.py b/sage/categories/entire_rings.py new file mode 100644
- + 1 r""" 2 EntireRings 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.rings import Rings 20 from sage.categories.category import Category 21 from sage.misc.cachefunc import cached_method 22 23 class EntireRings(Category): 24 """ 25 The category of entire rings 26 27 An entire ring (or non-commutative integral domains), is a not 28 necessarily commutative ring which has no zero divisors. 29 30 EXAMPLES: 31 sage: EntireRings() 32 Category of entire rings 33 sage: EntireRings().super_categories() 34 [Category of rings] 35 36 """ 37 38 @cached_method 39 def super_categories(self): 40 return [Rings()] 41 42 class ParentMethods: 43 pass 44 45 class ElementMethods: 46 pass -
new file sage/categories/enumerated_sets.py
diff --git a/sage/categories/enumerated_sets.py b/sage/categories/enumerated_sets.py new file mode 100644
- + 1 r""" 2 Enumerated Sets 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2009 Florent Hivert <Florent.Hivert@univ-rouen.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 20 from sage.structure.element import Element 21 from sage.structure.parent import Parent 22 from category_types import Category 23 from sage.misc.cachefunc import cached_method 24 from sage.categories.sets_cat import Sets 25 from sage.rings.integer import Integer 26 27 class EnumeratedSets(Category): 28 """ 29 The category of enumerated sets 30 31 An *enumerated set* is a *finite* or *countable* set or multiset together 32 with a canonical enumeration of its elements; Conceptually, this is very 33 similar to an imutable list. The main differences lies in the names and 34 the return typeof the methods, and of course the fact that the list of 35 element is not supposed to be expanded in memory. Except in the unlikely 36 case where you want to implement an enumerated set for which you don't 37 know the cardinality, you should use one of the two sub-categories 38 ``FiniteEnumeratedSets()`` or ``InfiniteEnumeratedSets()``. 39 40 The goal of this category is threefold: 41 - to fix a common interface for all these sets; 42 - to provide a bunch of default implementations; 43 - to provide consistency tests. 44 45 The standard methods for an enumerated set ``S`` are: 46 47 - ``S.cardinality()``: the number of element of the set. This is the 48 equivalent for ``len`` on a list except that the return value is 49 specified to be a sage ``Integer`` or ``Infinity``, instead of a 50 python ``int``; 51 52 - ``iter(S)``: an iterator for the element of the set; 53 54 - ``S.list()``: the list of the element of the set when possible; raise a 55 NotImplementedError if the list is too large to be expanded in 56 memory. 57 58 - ``S.unrank(n)``: the ``n-th`` element of the set when ``n`` is a sage 59 ``Integer``. This is the equivanlent for ``l[n]`` on a list. 60 61 - ``S.rank(e)``: the position of the element ``e`` in the set; This is 62 equivalent to ``l.index(e)`` for a list except that return value is 63 specified to be a sage ``Integer``, instead of a python ``int``; 64 65 - ``S.first()``: the first object of the set; It is equivalent to 66 ``S.unrank(0)``; 67 68 - ``S.next(e)``: the object of the set which follows ``e``; It is 69 equivalent to ``S.unrank(S.rank(e)+1)``. 70 71 - ``S.random_element()``: a random generator for an element of the set; 72 Unless otherwise stated, for finite enumerated sets the probability 73 is uniform. 74 75 For examples and test see: 76 77 - FiniteEnumeratedSets().example() 78 - InfiniteEnumeratedSets().example() 79 80 81 EXAMPLES:: 82 83 sage: EnumeratedSets() 84 Category of enumerated sets 85 sage: EnumeratedSets().super_categories() 86 [Category of sets] 87 sage: EnumeratedSets().all_super_categories() 88 [Category of enumerated sets, Category of sets, Category of objects] 89 90 TESTS:: 91 92 sage: C = EnumeratedSets() 93 sage: loads(C.dumps()) == C 94 True """ 95 96 @cached_method 97 def super_categories(self): 98 return [Sets()] 99 100 101 class ParentMethods: 102 """ 103 Parent class for the enumerated set category 104 """ 105 106 def __iter__(self): 107 """ 108 An iterator for the enumerated set. 109 110 ``iter(self)`` allows the combinatorial class to be treated as an 111 iterator. This if the default implementation from the category 112 ``EnumeratedSet()`` it just goes through the iterator of the set 113 to count the number of objects. 114 115 By decreasing order of priority, the second column of the 116 following array shows which methods is used to define 117 ``__iter__``, when the methods of the first column are overloaded: 118 119 +------------------------+---------------------------------+ 120 | Needed methods | Default ``__iterator`` provided | 121 +========================+=================================+ 122 | ``first`` and ``next`` | ``_iterator_from_next`` | 123 +------------------------+---------------------------------+ 124 | ``unrank`` | ``_iterator_from_unrank`` | 125 +------------------------+---------------------------------+ 126 | ``list` | ``_iterator_from_next`` | 127 +------------------------+---------------------------------+ 128 129 If non of these are provided raise a ``NotImplementedError`` 130 131 EXAMPLES:: 132 133 We start with an example where nothing is implemented:: 134 135 sage: class broken(UniqueRepresentation, Parent): 136 ... def __init__(self): 137 ... Parent.__init__(self, category = EnumeratedSets()) 138 ... 139 sage: it = iter(broken()); [it.next(), it.next(), it.next()] 140 Traceback (most recent call last): 141 ... 142 NotImplementedError: iterator called but not implemented 143 144 Here is what happends when ``first`` and ``next`` are implemeted:: 145 146 sage: class set_first_next(UniqueRepresentation, Parent): 147 ... def __init__(self): 148 ... Parent.__init__(self, category = EnumeratedSets()) 149 ... def first(self): 150 ... return 0 151 ... def next(self, elt): 152 ... return elt+1 153 ... 154 sage: it = iter(set_first_next()); [it.next(), it.next(), it.next()] 155 [0, 1, 2] 156 157 Let's try with ``unrank``:: 158 159 sage: class set_unrank(UniqueRepresentation, Parent): 160 ... def __init__(self): 161 ... Parent.__init__(self, category = EnumeratedSets()) 162 ... def unrank(self, i): 163 ... return i + 5 164 ... 165 sage: it = iter(set_unrank()); [it.next(), it.next(), it.next()] 166 [5, 6, 7] 167 168 Let's finally try with ``list``:: 169 170 sage: class set_list(UniqueRepresentation, Parent): 171 ... def __init__(self): 172 ... Parent.__init__(self, category = EnumeratedSets()) 173 ... def list(self): 174 ... return [5, 6, 7] 175 ... 176 sage: it = iter(set_list()); [it.next(), it.next(), it.next()] 177 [5, 6, 7] 178 179 """ 180 #Check to see if .first() and .next() are overridden in the subclass 181 if ( self.first != self._first_from_iterator and 182 self.next != self._next_from_iterator ): 183 return self._iterator_from_next() 184 #Check to see if .unrank() is overridden in the subclass 185 elif self.unrank != self._unrank_from_iterator: 186 return self._iterator_from_unrank() 187 #Finally, check to see if .list() is overridden in the subclass 188 elif self.list != self._list_default: 189 return self._iterator_from_list() 190 else: 191 raise NotImplementedError, "iterator called but not implemented" 192 193 194 def cardinality(self): 195 """ 196 The cardinality of ``self``. 197 198 ``self.cardinality()`` should returns the cardinality of the set 199 ``self`` as a sage ``Integer`` or as ``+Infinity``. 200 201 This if the default implementation from the category 202 ``EnumeratedSet()`` it returns `NotImplementedError` since one does 203 not know if the set is finite or not. 204 205 EXAMPLES:: 206 207 sage: class broken(UniqueRepresentation, Parent): 208 ... def __init__(self): 209 ... Parent.__init__(self, category = EnumeratedSets()) 210 ... 211 sage: broken().cardinality() 212 Traceback (most recent call last): 213 ... 214 NotImplementedError: unknown cardinality 215 """ 216 raise NotImplementedError, "unknown cardinality" 217 218 def list(self): 219 """ 220 Returns an error since the cardinality of self is not known. 221 222 EXAMPLES:: 223 224 sage: class broken(UniqueRepresentation, Parent): 225 ... def __init__(self): 226 ... Parent.__init__(self, category = EnumeratedSets()) 227 ... 228 sage: broken().list() 229 Traceback (most recent call last): 230 ... 231 NotImplementedError: unknown cardinality 232 """ 233 raise NotImplementedError, "unknown cardinality" 234 _list_default = list # needed by the check system. 235 236 237 def _first_from_iterator(self): 238 """ 239 The "first" element of ``self``. 240 241 ``self.first()`` returns the first element of the set 242 ``self``. This is a generic implementation from the category 243 ``EnumeratedSet()`` which can be used when the method ``__iter__`` is 244 provided. 245 246 EXAMPLES:: 247 248 sage: C = FiniteEnumeratedSets().example() 249 sage: C.first() # indirect doctest 250 1 251 """ 252 it = self.__iter__() 253 return it.next() 254 first = _first_from_iterator 255 256 def _next_from_iterator(self, obj): 257 """ 258 The "next" element after ``obj`` in ``self``. 259 260 ``self.next(e)`` returns the element of the set ``self`` which 261 follows ``e``. This is a generic implementation from the category 262 ``EnumeratedSet()`` which can be used when the method ``__iter__`` 263 is provided. 264 265 Remark: It is rather slow !!! 266 267 EXAMPLES:: 268 269 sage: C = InfiniteEnumeratedSets().example() 270 sage: C._next_from_iterator(10) # indirect doctest 271 11 272 """ 273 it = iter(self) 274 el = it.next() 275 while el != obj: 276 el = it.next() 277 return it.next() 278 next = _next_from_iterator 279 280 281 def _unrank_from_iterator(self, r): 282 """ 283 The ``r``-th element of ``self`` 284 285 ``self.unrank(r)`` returns the ``r``-th element of self where 286 ``r`` is an integer between ``0`` and ``n-1`` where ``n`` is the 287 cardinality of ``self``. This is a generic implementation from the 288 category ``EnumeratedSet()`` which can be used when the method 289 ``__iter__`` is provided. It may be extermely slow. 290 291 EXAMPLES:: 292 293 sage: C = FiniteEnumeratedSets().example() 294 sage: C.unrank(2) # indirect doctest 295 3 296 sage: C.unrank(5) # indirect doctest 297 Traceback (most recent call last): 298 ... 299 ValueError: the value must be between 0 and 2 inclusive 300 """ 301 counter = 0 302 for u in self: 303 if counter == r: 304 return u 305 counter += 1 306 raise ValueError, "the value must be between %s and %s inclusive"%(0,counter-1) 307 unrank = _unrank_from_iterator 308 309 def _iterator_from_list(self): 310 """ 311 An iterator for the elements of ``self``. 312 313 ``self.iterator()`` returns an iterator for the element of the set 314 ``self``. This is a generic implementation from the category 315 ``EnumeratedSet()`` which can be used when the method ``list`` is 316 provided. 317 318 EXAMPLES:: 319 320 sage: C = FiniteEnumeratedSets().example() 321 sage: it = C._iterator_from_list() 322 sage: [it.next(), it.next(), it.next()] 323 [1, 2, 3] 324 """ 325 for x in self.list(): 326 yield x 327 328 def _iterator_from_next(self): 329 """ 330 An iterator for the elements of ``self``. 331 332 ``self.iterator()`` returns an iterator for the element of the set 333 ``self``. This is a generic implementation from the category 334 ``EnumeratedSet()`` which can be used when then methods ``first`` 335 and ``next`` are provided. 336 337 EXAMPLES:: 338 339 sage: C = InfiniteEnumeratedSets().example() 340 sage: it = C._iterator_from_next() 341 sage: [it.next(), it.next(), it.next(), it.next(), it.next()] 342 [0, 1, 2, 3, 4] 343 """ 344 f = self.first() 345 yield f 346 while True: 347 try: 348 f = self.next(f) 349 except (TypeError, ValueError ): 350 break 351 352 if f is None or f is False : 353 break 354 else: 355 yield f 356 357 def _iterator_from_unrank(self): 358 """ 359 An iterator for the elements of ``self``. 360 361 ``self.iterator()`` returns an iterator for the element of the set 362 ``self``. This is a generic implementation from the category 363 ``EnumeratedSet()`` which can be used when the method ``unrank`` is 364 provided. 365 366 EXAMPLES:: 367 368 sage: C = InfiniteEnumeratedSets().example() 369 sage: it = C._iterator_from_unrank() 370 sage: [it.next(), it.next(), it.next(), it.next(), it.next()] 371 [0, 1, 2, 3, 4] 372 """ 373 r = 0 374 u = self.unrank(r) 375 yield u 376 while True: 377 r += 1 378 try: 379 u = self.unrank(r) 380 except (TypeError, ValueError, IndexError): 381 break 382 383 if u == None: 384 break 385 else: 386 yield u 387 388 389 390 def _an_element_from_iterator(self): 391 """ 392 An element in ``self``. 393 394 ``self.an_element()`` returns a particular element of the set 395 ``self``. This is a generic implementation from the category 396 ``EnumeratedSet()`` which can be used when the method ``__iter__`` 397 is provided. 398 399 EXAMPLES:: 400 401 sage: C = FiniteEnumeratedSets().example() 402 sage: C.an_element() # indirect doctest 403 1 404 """ 405 it = self.__iter__() 406 return it.next() 407 _an_element_ = _an_element_from_iterator 408 409 #FIXME: use combinatorial_class_from_iterator once class_from_iterator.patch is in 410 def _some_elements_from_iterator(self): 411 """ 412 Some elements in ``self``. 413 414 ``self.some_element()`` returns an iterator for some particular 415 elements of the set ``self``. This is a generic implementation 416 from the category ``EnumeratedSet()`` which can be used when the 417 method ``__iter__`` is provided. 418 419 EXAMPLES:: 420 421 sage: C = FiniteEnumeratedSets().example() 422 sage: list(C.some_elements()) # indirect doctest 423 [1, 2, 3] 424 """ 425 nb = 0 426 for i in self: 427 yield i 428 nb += 1 429 if nb >= 100: 430 break 431 some_elements = _some_elements_from_iterator 432 433 def random_element(self): 434 """ 435 A random element in ``self``. 436 437 ``self.random_element()`` should returns a random element in 438 ``self``. This is a generic implementation from the category 439 ``EnumeratedSet()`` it raise a ``NotImplementedError`` since one 440 does not know if the set is finite. 441 442 EXAMPLES:: 443 444 sage: class broken(UniqueRepresentation, Parent): 445 ... def __init__(self): 446 ... Parent.__init__(self, category = EnumeratedSets()) 447 ... 448 sage: broken().random_element() 449 Traceback (most recent call last): 450 ... 451 NotImplementedError: unknown cardinality 452 """ 453 raise NotImplementedError, "unknown cardinality" 454 455 456 457 # 458 # Consistency test suite for an enumerated set: 459 # 460 # If the enumerated set is large, one can stop some coeherency tests 461 # after looking at the first element by setting the following variable: 462 max_test_enumerated_set_loop=100 # TODO: Devise a sensible bound !! 463 ########## 464 def test_enumerated_set_contains(self, **options): 465 tester = self.tester(**options) 466 """ 467 Check the coherency between methods ``__contains__`` and ``__iter__``. 468 Automagically called by ``check()`` 469 470 TESTS:: 471 472 sage: C = FiniteEnumeratedSets().example() 473 sage: C.test_enumerated_set_contains() 474 sage: C.check() 475 476 Let's now break the class:: 477 478 sage: from sage.categories.examples.finite_enumerated_sets import Example 479 sage: class CCls(Example): 480 ... def __contains__(self, obj): 481 ... if obj == 3: 482 ... return False 483 ... else: 484 ... return obj in C 485 sage: CC = CCls() 486 sage: CC.check() 487 Traceback (most recent call last): 488 ... 489 AssertionError 490 """ 491 i = 0 492 for w in self: 493 tester.assertTrue(w in self) 494 i += 1 495 if i > self.max_test_enumerated_set_loop: 496 return 497 498 def test_enumerated_set_iter_list(self, **options): 499 tester = self.tester(**options) 500 """ 501 Check the coherency between methods ``list`` and ``__iter__`` 502 Automagically called by ``check()`` 503 504 EXAMPLES:: 505 506 sage: C = FiniteEnumeratedSets().example() 507 sage: C.test_enumerated_set_iter_list() 508 509 Let's now break the class:: 510 511 sage: from sage.categories.examples.finite_enumerated_sets import Example 512 sage: class CCls(Example): 513 ... def list(self): 514 ... return [1,2,3,4] 515 sage: CC = CCls() 516 sage: CC.check() 517 Traceback (most recent call last): 518 ... 519 AssertionError: 3 != 4 520 """ 521 if self.list != self._list_default: 522 ls = self.list() 523 i = 0 524 for obj in self: 525 tester.assertEqual(obj, ls[i]) 526 i += 1 527 if i > self.max_test_enumerated_set_loop: 528 return 529 tester.assertEqual(i, len(ls)) 530 531 class ElementMethods: 532 def rank(self): 533 return self.parent().rank(self) 534 535 -
new file sage/categories/euclidean_domains.py
diff --git a/sage/categories/euclidean_domains.py b/sage/categories/euclidean_domains.py new file mode 100644
- + 1 r""" 2 EuclideanDomains 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.category import Category 20 from sage.categories.basic import PrincipalIdealDomains 21 from sage.misc.cachefunc import cached_method 22 23 class EuclideanDomains(Category): 24 """ 25 The category of euclidean domains 26 constructive euclidean domain, i.e. one can divide producing a quotient and a 27 remainder where the remainder is either zero or is "smaller" than the divisor 28 29 30 EXAMPLES: 31 sage: EuclideanDomains() 32 Category of euclidean domains 33 sage: EuclideanDomains().super_categories() 34 [Category of principal ideal domains] 35 36 """ 37 38 @cached_method 39 def super_categories(self): 40 return [PrincipalIdealDomains()] 41 42 class ParentMethods: 43 pass 44 45 class ElementMethods: 46 pass -
new file sage/categories/examples/__init__.py
diff --git a/sage/categories/examples/__init__.py b/sage/categories/examples/__init__.py new file mode 100644
- + 1 -
new file sage/categories/examples/algebras_with_basis.py
diff --git a/sage/categories/examples/algebras_with_basis.py b/sage/categories/examples/algebras_with_basis.py new file mode 100644
- + 1 #***************************************************************************** 2 # Copyright (C) 2008 Nicolas Thiery 3 # 4 # Distributed under the terms of the GNU General Public License (GPL) 5 # 6 # This code is distributed in the hope that it will be useful, 7 # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 # General Public License for more details. 10 # 11 # The full text of the GPL is available at: 12 # 13 # http://www.gnu.org/licenses/ 14 #****************************************************************************** 15 16 from sage.misc.cachefunc import cached_method 17 from sage.sets.family import Family 18 from sage.categories.all import AlgebrasWithBasis 19 from sage.combinat.free_module import CombinatorialFreeModule 20 21 class MyGroupAlgebra(CombinatorialFreeModule): 22 r""" 23 A minimal example of algebra with basis: the group algebra of a group. 24 """ 25 26 def __init__(self, R, G): 27 self.group = G 28 CombinatorialFreeModule.__init__(self, R, G, category = AlgebrasWithBasis(R)) 29 30 def _repr_(self): 31 return "The group algebra of %s over %s"%(self.group, self.base_ring()) 32 33 @cached_method 34 def one_basis(self): 35 return self.group.one() 36 37 def product_on_basis(self, g1, g2): 38 return self.basis()[g1 * g2] 39 40 @cached_method 41 def algebra_generators(self): 42 return Family(self.group.gens(), self.term) 43 44 def some_elements(self): 45 return self.basis() -
new file sage/categories/examples/finite_enumerated_sets.py
diff --git a/sage/categories/examples/finite_enumerated_sets.py b/sage/categories/examples/finite_enumerated_sets.py new file mode 100644
- + 1 2 ################################################################# 3 # # 4 # Examples # 5 # # 6 ################################################################# 7 from sage.structure.element import Element 8 from sage.structure.parent import Parent 9 from sage.structure.unique_representation import UniqueRepresentation 10 from sage.structure.element_wrapper import ElementWrapper 11 from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets 12 13 ################################################################# 14 # Example of an enumerated set 15 class Example(UniqueRepresentation, Parent): 16 r""" 17 Example of an enumerated set 18 19 This class shows a minimal example of an enumerated set. 20 21 EXAMPLES:: 22 23 sage: C = FiniteEnumeratedSets().example() 24 sage: C.cardinality() #indirect doctest 25 3 26 sage: C.list() 27 [1, 2, 3] 28 29 To check if the different methods of the enumerated set C return 30 consistent results, on can simpli use:: 31 32 sage: C.check() 33 34 TESTS:: 35 36 sage: loads(C.dumps()) == C 37 True 38 """ 39 40 def __init__(self): 41 Parent.__init__(self, category = FiniteEnumeratedSets()) 42 43 def _repr_(self): 44 return "example of finite enumerated set" 45 46 def __contains__(self, o): 47 return o in [1,2,3] 48 49 def __iter__(self): 50 return iter([1,2,3]) 51 52 # temporarily needed because parent overload it. 53 def an_element(self): 54 return self._an_element_from_iterator() 55 56 class Element(ElementWrapper): 57 pass 58 -
new file sage/categories/examples/finite_semigroups.py
diff --git a/sage/categories/examples/finite_semigroups.py b/sage/categories/examples/finite_semigroups.py new file mode 100644
- + 1 #***************************************************************************** 2 # Copyright (C) 2008 Nicolas Thiery 3 # 4 # Distributed under the terms of the GNU General Public License (GPL) 5 # 6 # This code is distributed in the hope that it will be useful, 7 # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 # General Public License for more details. 10 # 11 # The full text of the GPL is available at: 12 # 13 # http://www.gnu.org/licenses/ 14 #****************************************************************************** 15 16 from sage.misc.lazy_attribute import lazy_attribute 17 from sage.misc.cachefunc import cached_method 18 from sage.sets.family import Family 19 from sage.categories.all import FiniteSemigroups 20 from sage.structure.parent import Parent 21 from sage.structure.unique_representation import UniqueRepresentation 22 from sage.structure.element_wrapper import ElementWrapper 23 24 25 # Example of a finite semi-group 26 class LRBand(UniqueRepresentation, Parent): 27 r""" 28 An example of finite semigroup 29 30 The purpose of this class is to provide a minimal template for 31 implementing of a finite semi-group. 32 33 EXAMPLES: 34 sage: S=FiniteSemigroups().example(); S 35 An example of finite semi-group: the left regular band generated by ('a', 'b', 'c', 'd') 36 37 This is the semi group generated by:: 38 39 sage: S.semigroup_generators() 40 Family ('a', 'b', 'c', 'd') 41 42 such that ``x^2 = x`` and `x y x = xy` for any `x` and `y` in `S`. 43 44 sage: S('dab') 45 'dab' 46 sage: S('dab') * S('acb') 47 'dabc' 48 49 # todo: profile the operations below 50 51 It follows that the elements of `S` are strings without 52 repetitions over the alphabet `a`, `b`, `c`, `d`:: 53 54 sage: S.list() 55 ['a', 'c', 'b', 'bd', 'bda', 'd', 'bdc', 'bc', 'bcd', 'cb', 56 'ca', 'ac', 'cba', 'ba', 'cbd', 'bdca', 'db', 'dc', 'cd', 57 'bdac', 'ab', 'abd', 'da', 'ad', 'cbad', 'acb', 'abc', 58 'abcd', 'acbd', 'cda', 'cdb', 'dac', 'dba', 'dbc', 'dbca', 59 'dcb', 'abdc', 'cdab', 'bcda', 'dab', 'acd', 'dabc', 'cbda', 60 'bca', 'dacb', 'bad', 'adb', 'bac', 'cab', 'adc', 'cdba', 61 'dca', 'cad', 'adbc', 'adcb', 'dbac', 'dcba', 'acdb', 'bacd', 62 'cabd', 'cadb', 'badc', 'bcad', 'dcab'] 63 64 There are 64 of them:: 65 66 sage: S.cardinality() 67 64 68 69 Indeed:: 70 71 sage: 4 * ( 1 + 3 * (1 + 2 * (1 + 1))) 72 64 73 74 As expected, all the elements of `S` are idempotents:: 75 76 sage: all( x.is_idempotent() for x in S ) 77 True 78 79 Now, let us look at the structure of the semigroup:: 80 81 sage: S = FiniteSemigroups().example(alphabet = ('a','b','c')) 82 sage: S.cayley_graph(side = "left", simple = True).plot() 83 sage: S.j_transversal_of_idempotents() 84 ['cab', 'ca', 'ab', 'cb', 'a', 'c', 'b'] 85 86 We conclude by running systematic tests on this semigroup:: 87 88 sage: S.check(verbose = True) 89 running test_an_element ... done 90 running test_associativity ... done 91 running test_element_pickling ... done 92 running test_enumerated_set_contains ... done 93 running test_enumerated_set_iter_cardinality ... done 94 running test_enumerated_set_iter_list ... done 95 running test_pickling ... done 96 running test_some_elements ... done 97 """ 98 99 def __init__(self, alphabet=('a','b','c','d')): 100 self.alphabet = alphabet 101 Parent.__init__(self, category = FiniteSemigroups()) 102 103 def _repr_(self): 104 return "An example of finite semi-group: the left regular band generated by %s"%(self.alphabet,) 105 106 def product(self, x, y): 107 assert x in self 108 assert y in self 109 x = x.value 110 y = y.value 111 return self(x + ''.join(c for c in y if c not in x)) 112 113 @cached_method 114 def semigroup_generators(self): 115 return Family([self(i) for i in self.alphabet]) 116 117 def an_element(self): 118 return self("acb") 119 120 class Element (ElementWrapper): 121 wrapped_class = str 122 123 Example = LRBand -
new file sage/categories/examples/hopf_algebras_with_basis.py
diff --git a/sage/categories/examples/hopf_algebras_with_basis.py b/sage/categories/examples/hopf_algebras_with_basis.py new file mode 100644
- + 1 #***************************************************************************** 2 # Copyright (C) 2008 Nicolas Thiery 3 # 4 # Distributed under the terms of the GNU General Public License (GPL) 5 # 6 # This code is distributed in the hope that it will be useful, 7 # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 # General Public License for more details. 10 # 11 # The full text of the GPL is available at: 12 # 13 # http://www.gnu.org/licenses/ 14 #****************************************************************************** 15 16 from sage.misc.cachefunc import cached_method 17 from sage.sets.family import Family 18 from sage.categories.all import HopfAlgebrasWithBasis 19 from sage.combinat.free_module import CombinatorialFreeModule 20 from sage.categories.all import tensor 21 22 class MyGroupAlgebra(CombinatorialFreeModule): 23 r""" 24 A minimal example of hopf algebra with basis: the group algebra of a group. 25 26 Todo: either merge with the example of AlgebrasWithBasis, or make 27 them really different examples. 28 """ 29 30 def __init__(self, R, G): 31 self.group = G 32 CombinatorialFreeModule.__init__(self, R, G, category = HopfAlgebrasWithBasis(R)) 33 34 def _repr_(self): 35 return "The Hopf algebra of the %s over %s"%(self.group, self.base_ring()) 36 37 @cached_method 38 def one_basis(self): 39 return self.group.one() 40 41 def product_on_basis(self, g1, g2): 42 return self.basis()[g1 * g2] 43 44 @cached_method 45 def algebra_generators(self): 46 return Family(self.group.gens(), self.term) 47 48 def coproduct_on_basis(self, g): 49 g = self.term(g) 50 return tensor([g, g]) -
new file sage/categories/examples/infinite_enumerated_sets.py
diff --git a/sage/categories/examples/infinite_enumerated_sets.py b/sage/categories/examples/infinite_enumerated_sets.py new file mode 100644
- + 1 ################################################################# 2 # # 3 # Examples # 4 # # 5 ################################################################# 6 7 from sage.structure.element import Element 8 from sage.structure.parent import Parent 9 from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets 10 from sage.structure.unique_representation import UniqueRepresentation 11 from sage.rings.integer import Integer 12 ################################################################# 13 # Example of an infinite enumerated set 14 class NonNegativeIntegers(UniqueRepresentation, Parent): 15 r""" 16 Example of an enumerated set 17 18 This class shows an example of an infinite enumerated set. 19 20 EXAMPLES:: 21 sage: from sage.categories.examples.infinite_enumerated_sets import NonNegativeIntegers 22 sage: NN = NonNegativeIntegers() 23 sage: NN 24 Set of non negative integers 25 sage: NN.cardinality() 26 +Infinity 27 sage: NN.check() 28 sage: NN.list() 29 Traceback (most recent call last): 30 ... 31 NotImplementedError: infinite list 32 sage: NN.element_class 33 <type 'sage.rings.integer.Integer'> 34 sage: it = iter(NN) 35 sage: [it.next(), it.next(), it.next(), it.next(), it.next()] 36 [0, 1, 2, 3, 4] 37 sage: x = it.next(); type(x) 38 <type 'sage.rings.integer.Integer'> 39 sage: x.parent() 40 Integer Ring 41 sage: x+3 42 8 43 sage: NN(15) 44 15 45 46 To check if the different methods of the enumerated set C return 47 consistent results, on can simpli use:: 48 49 sage: NN.check() 50 """ 51 52 def __init__(self): 53 Parent.__init__(self, category = InfiniteEnumeratedSets()) 54 55 def __repr__(self): 56 return "Set of non negative integers" 57 58 def __contains__(self, elt): 59 return Integer(elt) >= Integer(0) 60 61 def __iter__(self): 62 i = self._element_constructor_(0) 63 while True: 64 yield self._element_constructor_(i) 65 i += 1 66 ## FIXME : This allows to catch infinite loop during debugging" 67 ## FIXME : remove the following two lines, 68 if i > 200: 69 raise ValueError, "Infinite loop during DEBUG! TODO: remove me" 70 71 def __call__(self, elt): 72 if elt in self: 73 return self._element_constructor_(elt) 74 75 def an_element(self): 76 return self._element_constructor_(42) 77 78 def first(self): 79 return self._element_constructor_(0) 80 81 def next(self, o): 82 return self._element_constructor_(o+1) 83 84 def _element_constructor_(self, elt): 85 return self.element_class(elt) 86 87 Element = Integer 88 89 -
new file sage/categories/examples/monoids.py
diff --git a/sage/categories/examples/monoids.py b/sage/categories/examples/monoids.py new file mode 100644
- + 1 #***************************************************************************** 2 # Copyright (C) 2008 Nicolas M. Thiery <nthiery at users.sf.net> 3 # 4 # Distributed under the terms of the GNU General Public License (GPL) 5 # 6 # This code is distributed in the hope that it will be useful, 7 # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 # General Public License for more details. 10 # 11 # The full text of the GPL is available at: 12 # 13 # http://www.gnu.org/licenses/ 14 #****************************************************************************** 15 16 from sage.misc.cachefunc import cached_method 17 from sage.structure.parent import Parent 18 from sage.structure.element import Element 19 from sage.structure.unique_representation import UniqueRepresentation 20 from sage.structure.element_wrapper import ElementWrapper 21 from sage.categories.all import Monoids 22 from sage.sets.family import Family 23 from semigroups import FreeSemigroup 24 25 class FreeMonoid(FreeSemigroup): 26 r""" 27 An example of monoid 28 29 The purpose of this class is to provide a minimal template for 30 implementing of a monoid. 31 32 EXAMPLES:: 33 34 sage: S = Monoids().example(); S 35 An example of monoid: the free monoid generated by ('a', 'b', 'c', 'd') 36 37 sage: S.category() 38 Category of monoids 39 40 This is the free semigroup generated by:: 41 42 sage: S.semigroup_generators() 43 Family ('a', 'b', 'c', 'd') 44 45 sage: S('dab') * S('acb') 46 'dabacb' 47 48 We conclude by running systematic tests on this monoid:: 49 50 sage: S.check(verbose = True) 51 running test_an_element ... done 52 running test_associativity ... done 53 running test_element_pickling ... done 54 running test_one ... done 55 running test_pickling ... done 56 running test_prod ... done 57 running test_some_elements ... done 58 """ 59 60 def __init__(self, alphabet=('a','b','c','d')): 61 self.alphabet = alphabet 62 Parent.__init__(self, category = Monoids()) 63 64 def _repr_(self): 65 return "An example of monoid: the free monoid generated by %s"%(self.alphabet,) 66 67 @cached_method 68 def one(self): 69 return self("") 70 71 def an_element(self): 72 return self("acbabaca") 73 74 class Element (ElementWrapper): 75 wrapped_class = str 76 77 Example = FreeMonoid -
new file sage/categories/examples/semigroups.py
diff --git a/sage/categories/examples/semigroups.py b/sage/categories/examples/semigroups.py new file mode 100644
- + 1 #***************************************************************************** 2 # Copyright (C) 2008 Nicolas Thiery 3 # 4 # Distributed under the terms of the GNU General Public License (GPL) 5 # 6 # This code is distributed in the hope that it will be useful, 7 # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 # General Public License for more details. 10 # 11 # The full text of the GPL is available at: 12 # 13 # http://www.gnu.org/licenses/ 14 #****************************************************************************** 15 16 from sage.misc.cachefunc import cached_method 17 from sage.structure.parent import Parent 18 from sage.structure.element import Element 19 from sage.structure.unique_representation import UniqueRepresentation 20 from sage.structure.element_wrapper import ElementWrapper 21 from sage.categories.all import Semigroups 22 from sage.sets.family import Family 23 24 class LeftmostProductSemigroup(UniqueRepresentation, Parent): 25 r""" 26 An example of semigroup 27 28 This class illustrates a minimal implementation of a semigroup. 29 30 EXAMPLES: 31 sage: S = Semigroups().example(); S 32 The leftmost-product semigroup 33 34 This is the semigroup which contains all sort of objects: 35 36 sage: S.some_elements() 37 [3, 42, 'a', 3.3999999999999999, 'raton laveur'] 38 39 with product rule is given by $a \times b = a$ for all $a,b$. 40 41 sage: S('hello') * S('world') 42 'hello' 43 44 sage: S(3)*S(1)*S(2) 45 3 46 47 sage: S(3)^12312321312321 48 3 49 50 sage: S.check(verbose = True) 51 running test_an_element ... done 52 running test_associativity ... done 53 running test_element_pickling ... done 54 running test_pickling ... done 55 running test_some_elements ... done 56 """ 57 58 def __init__(self): 59 Parent.__init__(self, category = Semigroups()) 60 61 def _repr_(self): 62 return "The leftmost-product semigroup" 63 64 def product(self, x, y): 65 assert x in self 66 assert y in self 67 return x 68 69 def an_element(self): 70 return self(42) 71 72 def some_elements(self): 73 return [self(i) for i in [3, 42, "a", 3.4, "raton laveur"]] 74 75 class Element(ElementWrapper): 76 def is_idempotent(self): 77 """ 78 Trivial implementation of ``Semigroups.Element.is_idempotent`` 79 80 All elements of this monoid are idempotent! 81 """ 82 return True 83 84 85 class FreeSemigroup(UniqueRepresentation, Parent): 86 r""" 87 An example of semigroup 88 89 The purpose of this class is to provide a minimal template for 90 implementing of a semigroup. 91 92 EXAMPLES: 93 sage: S=Semigroups().example("free"); S 94 An example of semigroup: the free semigroup generated by ('a', 'b', 'c', 'd') 95 96 This is the free semi group generated by:: 97 98 sage: S.semigroup_generators() 99 Family ('a', 'b', 'c', 'd') 100 101 sage: S('dab') * S('acb') 102 'dabacb' 103 104 We conclude by running systematic tests on this semigroup:: 105 106 sage: S.check(verbose = True) 107 running test_an_element ... done 108 running test_associativity ... done 109 running test_element_pickling ... done 110 running test_pickling ... done 111 running test_some_elements ... done 112 """ 113 114 def __init__(self, alphabet=('a','b','c','d')): 115 self.alphabet = alphabet 116 Parent.__init__(self, category = Semigroups()) 117 118 def _repr_(self): 119 return "An example of semigroup: the free semigroup generated by %s"%(self.alphabet,) 120 121 def product(self, x, y): 122 assert x in self 123 assert y in self 124 return self(x.value + y.value) 125 126 @cached_method 127 def semigroup_generators(self): 128 return Family([self(i) for i in self.alphabet]) 129 130 def an_element(self): 131 return self("acbabaca") 132 133 class Element (ElementWrapper): 134 wrapped_class = str 135 136 137 138 class SubQuotientOfLeftmostProductSemigroup(UniqueRepresentation, Parent): 139 r""" 140 Example of a sub-quotient semigroup 141 142 EXAMPLES:: 143 144 sage: S = Semigroups().SubQuotients().example(); S 145 A subquotient of The leftmost-product semigroup 146 147 This is the quotient of:: 148 149 sage: S.ambient() 150 The leftmost-product semigroup 151 152 by setting `x=42` for any `x\geq 42`:: 153 154 sage: S(100) 155 42 156 sage: S(100) == S(42) 157 True 158 159 sage: S(1)*S(2) == S(1) 160 True 161 162 TESTS:: 163 164 sage: S.check(verbose = True) 165 running test_an_element ... done 166 running test_associativity ... done 167 running test_element_pickling ... done 168 running test_pickling ... done 169 running test_some_elements ... done 170 171 """ 172 def _element_constructor_(self, x): 173 return self.retract(self.ambient()(x)) 174 175 def __init__(self): 176 Parent.__init__(self, category = Semigroups().SubQuotients()) 177 178 def ambient(self): 179 return Semigroups().example() 180 181 def lift(self, x): 182 assert x in self 183 return x.value 184 185 def the_answer(self): 186 return self.retract(self.ambient()(42)) 187 188 def an_element(self): 189 return self.the_answer() 190 191 def some_elements(self): 192 return (self.retract(self.ambient()(i)) 193 for i in [1, 2, 3, 8, 42, 100]) 194 195 def retract(self, x): 196 from sage.rings.integer_ring import ZZ 197 assert x in self.ambient() and x.value in ZZ 198 if x.value > 42: 199 return self.the_answer() 200 else: 201 return self.element_class(x, parent = self) 202 203 class Element(ElementWrapper): 204 pass 205 -
new file sage/categories/examples/semigroups_cython.pyx
diff --git a/sage/categories/examples/semigroups_cython.pyx b/sage/categories/examples/semigroups_cython.pyx new file mode 100644
- + 1 from sage.structure.parent import Parent 2 from sage.structure.element cimport Element 3 from sage.categories.all import Category, Semigroups 4 from sage.misc.cachefunc import cached_method 5 from sage.categories.examples.semigroups import LeftmostProductSemigroup as LeftmostProductSemigroupPython 6 7 class DummyClass: 8 def method(self): 9 pass 10 11 cdef class DummyCClass: 12 def method(self): 13 pass 14 15 cpdef cpmethod(self): 16 pass 17 18 instancemethod = type(DummyClass.method) 19 method_descriptor = type(DummyCClass.method) 20 21 cdef class IdempotentSemigroupsElement(Element): 22 def _pow_(self, i): 23 assert i > 0 24 return self 25 26 cpdef is_idempotent_cpdef(self): 27 return True 28 29 class IdempotentSemigroups(Category): 30 @cached_method 31 def super_categories(self): 32 return [Semigroups()] 33 34 ElementMethods = IdempotentSemigroupsElement 35 36 37 cdef class LeftmostProductSemigroupElement(Element): 38 cdef object _value 39 40 def __init__(self, value, parent): 41 Element.__init__(self, parent = parent) 42 self._value = value 43 44 def _repr_(self): 45 return repr(self._value) 46 47 def __reduce__(self): 48 return LeftmostProductSemigroupElement, (self._value, self._parent) 49 50 def __cmp__(LeftmostProductSemigroupElement self, LeftmostProductSemigroupElement other): 51 return cmp(self._value, other._value) 52 53 def __getattr__(self, name): 54 result = getattr(self.parent().category().element_class, name) 55 if isinstance(result, instancemethod): 56 return instancemethod(result.im_func, self, self.__class__) 57 elif isinstance(result, method_descriptor): 58 return result # should bind the method descriptor to appropriate object 59 else: 60 return result 61 62 # Apparently, python looks for __mul__, __pow__, ... in the 63 # class of self rather than in self itself. No big deal, since 64 # those will usually be defined in a cython super class of 65 # this class 66 def __mul__(self, other): 67 return self._mul_(other) 68 69 cpdef _mul_(self, other): 70 return self.parent().product(self, other) 71 72 def __pow__(self, i, dummy): 73 return self._pow_(i) 74 75 class LeftmostProductSemigroup(LeftmostProductSemigroupPython): 76 r""" 77 An example of semigroup 78 79 This class illustrates a minimal implementation of a semi-group 80 where the element class is an extension type, and still gets code 81 from the category. Also, the category itself includes some cython 82 methods. 83 84 This is purely a proof of concept. The code obviously needs refactorisation! 85 86 Comments: 87 - nested classes seem not to be currently supported by cython 88 - one cannot play ugly use class surgery tricks (as with _mul_parent) 89 available operations should really be declared to the coercion model! 90 91 EXAMPLES: 92 sage: from sage.categories.examples.semigroups_cython import LeftmostProductSemigroup 93 sage: S = LeftmostProductSemigroup(); S 94 The leftmost-product semigroup 95 96 This is the semigroup which contains all sort of objects: 97 98 sage: S.some_elements() 99 [3, 42, 'a', 3.3999999999999999, 'raton laveur'] 100 101 with product rule is given by $a \times b = a$ for all $a,b$. 102 103 sage: S('hello') * S('world') 104 'hello' 105 106 sage: S(3)*S(1)*S(2) 107 3 108 109 sage: S(3)^12312321312321 # todo: not implemented (see below) 110 3 111 112 sage: S.check(verbose = True) 113 running test_an_element ... done 114 running test_associativity ... done 115 running test_element_pickling ... done 116 running test_pickling ... done 117 running test_some_elements ... done 118 119 # That's really the only method which is obtained from the category ... 120 sage: S(42).is_idempotent 121 <bound method LeftmostProductSemigroupElement.is_idempotent of 42> 122 sage: S(42).is_idempotent() 123 True 124 125 sage: S(42)._pow_ # how to bind it? 126 <method '_pow_' of 'sage.categories.examples.semigroups_cython.IdempotentSemigroupsElement' objects> 127 sage: S(42)^10 # todo: not implemented 128 42 129 130 sage: S(42).is_idempotent_cpdef # how to bind it? 131 <method 'is_idempotent_cpdef' of 'sage.categories.examples.semigroups_cython.IdempotentSemigroupsElement' objects> 132 sage: S(42).is_idempotent_cpdef() # todo: not implemented 133 True 134 """ 135 136 def __init__(self): 137 Parent.__init__(self, category = IdempotentSemigroups()) 138 139 Element = LeftmostProductSemigroupElement -
new file sage/categories/examples/sets_cat.py
diff --git a/sage/categories/examples/sets_cat.py b/sage/categories/examples/sets_cat.py new file mode 100644
- + 1 from sage.structure.parent import Parent 2 from sage.categories.sets_cat import Sets 3 from sage.rings.integer import Integer, IntegerWrapper 4 from sage.rings.integer_ring import IntegerRing 5 from sage.rings.arith import is_prime 6 from sage.structure.unique_representation import UniqueRepresentation 7 8 9 class PrimeNumbers(UniqueRepresentation, Parent): 10 """ 11 An example of parent in the category sets: the set of prime numbers. 12 13 EXAMPLES:: 14 15 sage: P = Sets().example(facade=False) 16 sage: P(12) 17 Traceback (most recent call last): 18 ... 19 AssertionError: 12 is not a prime number 20 sage: a = P.an_element() 21 sage: a.parent() 22 Set of prime numbers 23 sage: x = P(13); x 24 13 25 sage: x.is_prime() 26 True 27 sage: type(x) 28 <class 'sage.categories.examples.sets_cat.PrimeNumbers_with_category.element_class'> 29 sage: x.parent() 30 Set of prime numbers 31 sage: P(13) in P 32 True 33 sage: y = x+1; y 34 14 35 sage: type(y) 36 <type 'sage.rings.integer.Integer'> 37 sage: y.parent() 38 Integer Ring 39 sage: type(P(13)+P(17)) 40 <type 'sage.rings.integer.Integer'> 41 sage: type(P(2)+P(3)) 42 <type 'sage.rings.integer.Integer'> 43 44 sage: P.check(verbose=True) 45 running test_an_element ... done 46 running test_element_pickling ... done 47 running test_pickling ... done 48 running test_some_elements ... done 49 """ 50 51 def __init__(self): 52 """ 53 TESTS:: 54 55 sage: P = Sets().example(facade=False) 56 sage: type(P(13)+P(17)) 57 <type 'sage.rings.integer.Integer'> 58 sage: type(P(2)+P(3)) 59 <type 'sage.rings.integer.Integer'> 60 """ 61 Parent.__init__(self, category = Sets()) 62 self._populate_coercion_lists_(embedding=IntegerRing()) 63 64 def _repr_(self): 65 """ 66 TESTS:: 67 68 sage: P = Sets().example(facade=False); P 69 Set of prime numbers 70 """ 71 return "Set of prime numbers" 72 73 def an_element(self): 74 """ 75 TESTS:: 76 77 sage: P = Sets().example(facade=False) 78 sage: x = P.an_element(); x 79 47 80 sage: x.parent() 81 Set of prime numbers 82 """ 83 return self(47) 84 85 def __contains__(self, p): 86 """ 87 TESTS:: 88 89 sage: P = Sets().example(facade=False) 90 sage: 13 in P, P(13) in P 91 (False, True) 92 sage: 12 in P 93 False 94 """ 95 return p.parent() is self 96 97 class Element(IntegerWrapper): 98 def __init__(self, p, parent): 99 """ 100 TESTS:: 101 102 sage: P = Sets().example(facade=False) 103 sage: P(12) 104 Traceback (most recent call last): 105 ... 106 AssertionError: 12 is not a prime number 107 sage: x = P(13); type(x) 108 <class 'sage.categories.examples.sets_cat.PrimeNumbers_with_category.element_class'> 109 sage: x.parent() is P 110 True 111 """ 112 assert is_prime(p), "%s is not a prime number"%(p) 113 IntegerWrapper.__init__(self, p, parent=parent) 114 115 def is_prime(self): 116 """ 117 TESTS:: 118 119 sage: P = Sets().example(facade=False) 120 sage: P.an_element().is_prime() 121 True 122 """ 123 return True 124 125 class PrimeNumbers_Facade(UniqueRepresentation, Parent): 126 """ 127 EXAMPLES:: 128 129 sage: P = Sets().example(facade=True) 130 sage: P(12) 131 Traceback (most recent call last): 132 ... 133 AssertionError: 12 is not a prime number 134 sage: a = P.an_element() 135 sage: a.parent() 136 Integer Ring 137 sage: x = P(13); x 138 13 139 sage: type(x) 140 <type 'sage.rings.integer.Integer'> 141 sage: x.parent() 142 Integer Ring 143 sage: 13 in P 144 True 145 sage: 12 in P 146 False 147 sage: y = x+1; y 148 14 149 sage: type(y) 150 <type 'sage.rings.integer.Integer'> 151 152 sage: P.check(verbose=True) 153 running test_an_element ... done 154 running test_element_pickling ... done 155 running test_pickling ... done 156 running test_some_elements ... done 157 """ 158 def __init__(self): 159 Parent.__init__(self, category = Sets()) 160 161 def _repr_(self): 162 return "Set of prime numbers (facade implementation)" 163 164 def an_element(self): 165 return self(47) # if speed is needed, call: self.element_class(47) 166 167 def __contains__(self, p): 168 """ 169 TESTS:: 170 171 sage: P = Sets().example(facade=True) 172 sage: 13 in P 173 True 174 sage: 12 in P 175 False 176 """ 177 return isinstance(p, Integer) and p.is_prime() 178 179 def _element_constructor_(self, e): 180 p = self.element_class(e) 181 assert is_prime(p), "%s is not a prime number"%(p) 182 return p 183 184 element_class = Integer 185 -
new file sage/categories/fields.py
diff --git a/sage/categories/fields.py b/sage/categories/fields.py new file mode 100644
- + 1 r""" 2 Fields 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # David Kohel <kohel@maths.usyd.edu> and 7 # William Stein <wstein@math.ucsd.edu> 8 # Nicolas M. Thiery <nthiery at users.sf.net> 9 # 10 # Distributed under the terms of the GNU General Public License (GPL) 11 # 12 # This code is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 # General Public License for more details. 16 # 17 # The full text of the GPL is available at: 18 # 19 # http://www.gnu.org/licenses/ 20 #****************************************************************************** 21 22 from sage.categories.category import Category 23 from sage.misc.cachefunc import cached_method 24 25 class Fields(Category): 26 """ 27 The category of fields 28 commutative fields, i.e. commutative rings where all non-zero elements have 29 multiplicative inverses 30 31 EXAMPLES: 32 sage: K = Fields() 33 sage: K 34 Category of fields 35 sage: Fields().super_categories() 36 [Category of euclidean domains, Category of unique factorization domains, Category of division rings] 37 38 sage: K(IntegerRing()) 39 Rational Field 40 sage: K(PolynomialRing(GF(3), 'x')) 41 Fraction Field of Univariate Polynomial Ring in x over 42 Finite Field of size 3 43 sage: K(RealField()) 44 Real Field with 53 bits of precision 45 46 TESTS: 47 sage: C = Fields() 48 sage: loads(C.dumps()) == C 49 True 50 51 """ 52 53 @cached_method 54 def super_categories(self): 55 from sage.categories.basic import EuclideanDomains, UniqueFactorizationDomains, DivisionRings 56 return [EuclideanDomains(), UniqueFactorizationDomains(), DivisionRings()] 57 58 # for backward compatibility 59 def __contains__(self, x): 60 from sage.rings.field import is_Field 61 return is_Field(x) 62 63 def __call__(self, x): 64 if x in self: 65 return x 66 try: 67 return x.fraction_field() 68 except AttributeError: 69 raise TypeError, "unable to associate a field to %s"%x 70 71 class ParentMethods: 72 pass 73 74 class ElementMethods: 75 pass -
new file sage/categories/finite_dimensional_algebras_with_basis.py
diff --git a/sage/categories/finite_dimensional_algebras_with_basis.py b/sage/categories/finite_dimensional_algebras_with_basis.py new file mode 100644
- + 1 r""" 2 FiniteDimensionalAlgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import FiniteDimensionalModulesWithBasis, AlgebrasWithBasis 21 from sage.misc.cachefunc import cached_method 22 23 class FiniteDimensionalAlgebrasWithBasis(Category_over_base_ring): 24 """ 25 The category of finite dimensional algebras with a distinguished basis 26 27 EXAMPLES: 28 sage: FiniteDimensionalAlgebrasWithBasis(QQ) 29 Category of finite dimensional algebras with basis over Rational Field 30 sage: FiniteDimensionalAlgebrasWithBasis(QQ).super_categories() 31 [Category of finite dimensional modules with basis over Rational Field, Category of algebras with basis over Rational Field] 32 33 """ 34 35 @cached_method 36 def super_categories(self): 37 R = self.base_ring() 38 return [FiniteDimensionalModulesWithBasis(R), AlgebrasWithBasis(R)] 39 40 class ParentMethods: 41 pass 42 43 class ElementMethods: 44 def on_left_matrix(self, new_BR = None): 45 """ 46 Returns the matrix of the action of self on the algebra my 47 multiplication on the left 48 49 If new_BR is specified, then the matrix will be over new_BR. 50 51 TODO: split into to parts 52 - build the endomorphism of multiplication on the left 53 - build the matrix of an endomorphism 54 55 EXAMPLES: 56 sage: QS3 = SymmetricGroupAlgebra(QQ, 3) 57 sage: a = QS3([2,1,3]) 58 sage: a._matrix_() 59 [0 0 1 0 0 0] 60 [0 0 0 0 1 0] 61 [1 0 0 0 0 0] 62 [0 0 0 0 0 1] 63 [0 1 0 0 0 0] 64 [0 0 0 1 0 0] 65 sage: a._matrix_(RDF) 66 [0.0 0.0 1.0 0.0 0.0 0.0] 67 [0.0 0.0 0.0 0.0 1.0 0.0] 68 [1.0 0.0 0.0 0.0 0.0 0.0] 69 [0.0 0.0 0.0 0.0 0.0 1.0] 70 [0.0 1.0 0.0 0.0 0.0 0.0] 71 [0.0 0.0 0.0 1.0 0.0 0.0] 72 73 """ 74 parent = self.parent() 75 76 if parent.get_order() is None: 77 cc = parent._combinatorial_class 78 else: 79 cc = parent.get_order() 80 81 BR = parent.base_ring() 82 if new_BR is None: 83 new_BR = BR 84 85 from sage.matrix.all import MatrixSpace 86 MS = MatrixSpace(new_BR, parent.dimension(), parent.dimension()) 87 l = [ (self*parent(m)).to_vector() for m in cc ] 88 return MS(l).transpose() 89 90 _matrix_ = on_left_matrix # For temporary backward compatibility 91 to_matrix = on_left_matrix -
new file sage/categories/finite_dimensional_bialgebras_with_basis.py
diff --git a/sage/categories/finite_dimensional_bialgebras_with_basis.py b/sage/categories/finite_dimensional_bialgebras_with_basis.py new file mode 100644
- + 1 r""" 2 FiniteDimensionalBialgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import FiniteDimensionalAlgebrasWithBasis, FiniteDimensionalCoalgebrasWithBasis, Bialgebras 21 from sage.misc.cachefunc import cached_method 22 23 class FiniteDimensionalBialgebrasWithBasis(Category_over_base_ring): 24 """ 25 The category of finite dimensional bialgebras with a distinguished basis 26 27 EXAMPLES:: 28 29 sage: FiniteDimensionalBialgebrasWithBasis(QQ) 30 Category of finite dimensional bialgebras with basis over Rational Field 31 sage: FiniteDimensionalBialgebrasWithBasis(QQ).super_categories() 32 [Category of finite dimensional algebras with basis over Rational Field, Category of finite dimensional coalgebras with basis over Rational Field, Category of bialgebras over Rational Field] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [FiniteDimensionalAlgebrasWithBasis(R), FiniteDimensionalCoalgebrasWithBasis(R), Bialgebras(R)] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass -
new file sage/categories/finite_dimensional_coalgebras_with_basis.py
diff --git a/sage/categories/finite_dimensional_coalgebras_with_basis.py b/sage/categories/finite_dimensional_coalgebras_with_basis.py new file mode 100644
- + 1 r""" 2 FiniteDimensionalCoalgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import FiniteDimensionalModulesWithBasis, CoalgebrasWithBasis 21 from sage.misc.cachefunc import cached_method 22 23 class FiniteDimensionalCoalgebrasWithBasis(Category_over_base_ring): 24 """ 25 The category of finite dimensional coalgebras with a distinguished basis 26 27 EXAMPLES: 28 sage: FiniteDimensionalCoalgebrasWithBasis(QQ) 29 Category of finite dimensional coalgebras with basis over Rational Field 30 sage: FiniteDimensionalCoalgebrasWithBasis(QQ).super_categories() 31 [Category of finite dimensional modules with basis over Rational Field, Category of coalgebras with basis over Rational Field] 32 33 """ 34 35 @cached_method 36 def super_categories(self): 37 R = self.base_ring() 38 return [FiniteDimensionalModulesWithBasis(R), CoalgebrasWithBasis(R)] 39 40 class ParentMethods: 41 pass 42 43 class ElementMethods: 44 pass -
new file sage/categories/finite_dimensional_hopf_algebras_with_basis.py
diff --git a/sage/categories/finite_dimensional_hopf_algebras_with_basis.py b/sage/categories/finite_dimensional_hopf_algebras_with_basis.py new file mode 100644
- + 1 r""" 2 FiniteDimensionalHopfAlgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import FiniteDimensionalBialgebrasWithBasis, HopfAlgebrasWithBasis 21 from sage.misc.cachefunc import cached_method 22 23 class FiniteDimensionalHopfAlgebrasWithBasis(Category_over_base_ring): 24 """ 25 The category of finite dimensional Hopf algebras with a distinguished basis 26 27 EXAMPLES:: 28 29 sage: FiniteDimensionalHopfAlgebrasWithBasis(QQ) # fixme: Hopf should be capitalized 30 Category of finite dimensional hopf algebras with basis over Rational Field 31 sage: FiniteDimensionalHopfAlgebrasWithBasis(QQ).super_categories() 32 [Category of finite dimensional bialgebras with basis over Rational Field, Category of hopf algebras with basis over Rational Field] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [FiniteDimensionalBialgebrasWithBasis(R), HopfAlgebrasWithBasis(R)] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass -
new file sage/categories/finite_dimensional_modules_with_basis.py
diff --git a/sage/categories/finite_dimensional_modules_with_basis.py b/sage/categories/finite_dimensional_modules_with_basis.py new file mode 100644
- + 1 r""" 2 FiniteDimensionalModulesWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import ModulesWithBasis 21 from sage.misc.cachefunc import cached_method 22 23 class FiniteDimensionalModulesWithBasis(Category_over_base_ring): 24 """ 25 The category of finite dimensional modules with a distinguished basis 26 27 EXAMPLES: 28 sage: FiniteDimensionalModulesWithBasis(QQ) 29 Category of finite dimensional modules with basis over Rational Field 30 sage: FiniteDimensionalModulesWithBasis(QQ).super_categories() 31 [Category of modules with basis over Rational Field] 32 33 """ 34 35 @cached_method 36 def super_categories(self): 37 R = self.base_ring() 38 return [ModulesWithBasis(R)] 39 40 class ParentMethods: 41 pass 42 43 class ElementMethods: 44 pass -
new file sage/categories/finite_enumerated_sets.py
diff --git a/sage/categories/finite_enumerated_sets.py b/sage/categories/finite_enumerated_sets.py new file mode 100644
- + 1 r""" 2 Finite Enumerated Sets 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2009 Florent Hivert <Florent.Hivert@univ-rouen.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 20 from category_types import Category 21 from sage.categories.enumerated_sets import EnumeratedSets 22 from sage.rings.integer import Integer 23 from sage.misc.cachefunc import cached_method 24 25 class FiniteEnumeratedSets(Category): 26 """ 27 The category of finite enumerated sets 28 29 EXAMPLES:: 30 31 sage: FiniteEnumeratedSets() 32 Category of finite enumerated sets 33 sage: FiniteEnumeratedSets().super_categories() 34 [Category of enumerated sets] 35 sage: FiniteEnumeratedSets().all_super_categories() 36 [Category of finite enumerated sets, 37 Category of enumerated sets, 38 Category of sets, 39 Category of objects] 40 41 TESTS:: 42 43 sage: C = FiniteEnumeratedSets() 44 sage: loads(C.dumps()) == C 45 True 46 """ 47 48 @cached_method 49 def super_categories(self): 50 return [EnumeratedSets()] 51 52 pass 53 54 def example(self): 55 """ 56 A simple example of a finite enumerated set. 57 58 EXAMPLES:: 59 60 sage: FiniteEnumeratedSets().example() 61 example of finite enumerated set 62 """ 63 from sage.categories.examples.finite_enumerated_sets import Example 64 return Example() 65 66 class ParentMethods: 67 """ 68 Parent class for the finite enumerated set category 69 """ 70 71 def _cardinality_from_iterator(self): 72 """ 73 The cardinality of ``self``. 74 75 ``self.cardinality()`` returns the cardinality of the set ``self`` 76 as a sage ``Integer`` or as ``+Infinity``. 77 78 This if the default implementation from the category 79 ``FiniteEnumeratedSet()`` it just goes through the iterator of the 80 set to count the number of objects. 81 82 EXAMPLES:: 83 84 sage: C = FiniteEnumeratedSets().example() 85 sage: C.cardinality() # indirect doctest 86 3 87 """ 88 c = Integer(0) 89 one = Integer(1) 90 for _ in self: 91 c += one 92 return c 93 #Set cardinality to the default implementation 94 cardinality = _cardinality_from_iterator 95 96 97 def _list_from_iterator(self): 98 """ 99 The list of elements ``self``. 100 101 ``self.list()`` returns the list of the element of the set 102 ``self``. This is the default implementation the category 103 ``EnumeratedSet()`` which builds the list from the iterator. 104 105 EXAMPLES:: 106 107 sage: C = FiniteEnumeratedSets().example() 108 sage: C.list() # indirect doctest 109 [1, 2, 3] 110 """ 111 return [x for x in self] 112 #Set list to the default implementation 113 _list_default = _list_from_iterator # needed by the check mechanism. 114 list = _list_default 115 116 117 def _random_element_from_unrank(self): 118 """ 119 A random element in ``self``. 120 121 ``self.random_element()`` returns a random element in ``self`` 122 with uniform probability. This is a generic implementation from 123 the category ``EnumeratedSet()`` which can be used when the method 124 ``unrank`` is provided. 125 126 EXAMPLES:: 127 128 sage: C = FiniteEnumeratedSets().example() 129 sage: C.random_element() 130 1 131 """ 132 from sage.misc.prandom import randint 133 c = self.cardinality() 134 r = randint(0, c-1) 135 return self.unrank(r) 136 #Set the default implementation of random 137 random_element = _random_element_from_unrank 138 139 @cached_method 140 def _last_from_iterator(self): 141 """ 142 The last element of ``self``. 143 144 ``self.last()`` returns the last element of ``self`` This is a 145 generic implementation from the category ``FiniteEnumeratedSet()`` 146 which can be used when the method ``__iter__`` is provided. 147 148 EXAMPLES:: 149 150 sage: C = FiniteEnumeratedSets().example() 151 sage: C.last() 152 3 153 """ 154 for i in self: 155 pass 156 return i 157 last = _last_from_iterator 158 159 def _last_from_unrank(self): 160 """ 161 The last element of ``self``. 162 163 ``self.last()`` returns the last element of ``self`` This is a 164 generic implementation from the category ``FiniteEnumeratedSet()`` 165 which can be used when the method ``unrank`` is provided. 166 167 EXAMPLES:: 168 169 sage: C = FiniteEnumeratedSets().example() 170 sage: C._last_from_unrank() 171 3 172 """ 173 return self.unrank(self.cardinality() -1) 174 175 def test_enumerated_set_iter_cardinality(self, **options): 176 tester = self.tester(**options) 177 """ 178 Check the coherency between methods ``cardinality`` and 179 ``__iter__``. Automagically called by ``check()`` 180 181 EXAMPLES:: 182 183 sage: C = FiniteEnumeratedSets().example() 184 sage: C.test_enumerated_set_iter_cardinality() 185 186 Let's now break the class:: 187 188 sage: from sage.categories.examples.finite_enumerated_sets import Example 189 sage: class CCls(Example): 190 ... def cardinality(self): 191 ... return 4 192 sage: CC = CCls() 193 sage: CC.check() 194 Traceback (most recent call last): 195 ... 196 AssertionError: 4 != 3 197 """ 198 if self.cardinality != self._cardinality_from_iterator: 199 tester.assertEqual(self.cardinality(), 200 self._cardinality_from_iterator()) 201 202 -
new file sage/categories/finite_fields.py
diff --git a/sage/categories/finite_fields.py b/sage/categories/finite_fields.py new file mode 100644
- + 1 r""" 2 Fields 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # David Kohel <kohel@maths.usyd.edu> and 7 # William Stein <wstein@math.ucsd.edu> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from sage.misc.cachefunc import cached_method 22 from sage.categories.category import Category 23 from sage.categories.all import Fields 24 from sage.rings.field import is_Field 25 26 class FiniteFields(Category): 27 """ 28 The category of finite fields 29 30 EXAMPLES: 31 EXAMPLES: 32 sage: K = FiniteFields() 33 sage: K 34 Category of finite fields 35 sage: FiniteField(17) in K 36 True 37 sage: RationalField() in K 38 False 39 sage: K(RationalField()) 40 Traceback (most recent call last): 41 ... 42 TypeError: unable to canonically associate a finite field to Rational Field 43 44 TESTS: 45 sage: C = FiniteFields() 46 sage: loads(C.dumps()) == C 47 True 48 49 """ 50 51 @cached_method 52 def super_categories(self): 53 return [Fields()] 54 55 def __contains__(self, x): 56 return is_Field(x) and x.is_finite() 57 58 def __call__(self, x): 59 if x in self: 60 return x 61 raise TypeError, "unable to canonically associate a finite field to %s"%x 62 # TODO: local dvr ring? 63 64 65 class ParentMethods: 66 pass 67 68 class ElementMethods: 69 pass -
new file sage/categories/finite_monoids.py
diff --git a/sage/categories/finite_monoids.py b/sage/categories/finite_monoids.py new file mode 100644
- + 1 r""" 2 Monoids 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.misc.cachefunc import cached_method 20 from sage.misc.all import attrcall 21 from sage.categories.category import Category, HomCategory 22 from sage.categories.category import Category 23 from sage.categories.finite_semigroups import FiniteSemigroups 24 from sage.categories.monoids import Monoids 25 26 27 class FiniteMonoids(Category): 28 """ 29 The category of finite monoids 30 31 EXAMPLES:: 32 33 sage: FiniteMonoids() 34 Category of finite monoids 35 sage: FiniteMonoids().super_categories() 36 [Category of finite semigroups, Category of monoids] 37 """ 38 39 @cached_method 40 def super_categories(self): 41 return [FiniteSemigroups(), Monoids()] 42 43 44 class ElementMethods: 45 def pseudo_order(self): 46 r""" 47 Returns the pair [k, j] with k minimal and $0\leq j <k$ such 48 that self^k = self^j. 49 50 Note that j is uniquely determined. 51 52 TODO: more appropriate name? 53 """ 54 self_powers = {self.parent().one(): 0} 55 k = 1 56 self_power_k = self 57 while not self_power_k in self_powers: 58 self_powers[self_power_k] = k 59 k += 1 60 self_power_k = self_power_k * self 61 return [k, self_powers[self_power_k]] 62 63 64 class HomCategory(HomCategory): 65 """ 66 The category of monoid morphisms 67 """ 68 pass -
new file sage/categories/finite_semigroups.py
diff --git a/sage/categories/finite_semigroups.py b/sage/categories/finite_semigroups.py new file mode 100644
- + 1 r""" 2 Semigroups 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # Florent Hivert <florent.hivert at univ-rouen.fr> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from sage.categories.category import Category 21 from sage.categories.semigroups import Semigroups 22 from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets 23 from sage.structure.unique_representation import UniqueRepresentation 24 from sage.structure.parent import Parent 25 from sage.structure.element import Element, generic_power 26 from sage.structure.element_wrapper import ElementWrapper 27 from sage.misc.cachefunc import cached_method 28 29 class FiniteSemigroups(Category): 30 """ 31 The category of (multiplicative) finite semigroups, 32 i.e. enumerated sets with an associative operation *. 33 34 EXAMPLES:: 35 36 sage: FiniteSemigroups() 37 Category of finite semigroups 38 sage: FiniteSemigroups().super_categories() 39 [Category of semigroups, Category of finite enumerated sets] 40 sage: FiniteSemigroups().all_super_categories() 41 [Category of finite semigroups, 42 Category of semigroups, 43 Category of finite enumerated sets, 44 Category of enumerated sets, 45 Category of sets, 46 Category of objects] 47 sage: FiniteSemigroups().example() 48 An example of finite semi-group: the left regular band generated by ('a', 'b', 'c', 'd') 49 50 TESTS:: 51 52 sage: C = Semigroups() 53 sage: loads(C.dumps()) == C 54 True 55 """ 56 @cached_method 57 def super_categories(self): 58 return [Semigroups(), FiniteEnumeratedSets()] 59 60 class ParentMethods: 61 def some_elements(self): 62 return self 63 64 def idempotents(self): 65 return [x for x in self if x.is_idempotent()] 66 67 def succ_generators(self, side = "both"): 68 r""" 69 INPUT: 70 - ``side``: "left", "right", or "both" 71 72 Returns the the successor function of the left 73 (resp. right, resp. two sided) Cayley graph of self. 74 75 This is a function which maps an element of self to all 76 the products of x by a generator of this semigroup, on the 77 left (resp. the right, resp. on both sides). 78 79 FIXME: find a better name for this method and for both 80 FIXME: should we return a set? a family? 81 82 EXAMPLES: 83 sage: S = FiniteSemigroups().example() 84 sage: S.succ_generators("left" )(S('ca')) 85 ('ac', 'bca', 'ca', 'dca') 86 sage: S.succ_generators("right")(S('ca')) 87 ('ca', 'cab', 'ca', 'cad') 88 sage: S.succ_generators("both" )(S('ca')) 89 ('ac', 'bca', 'ca', 'dca', 'ca', 'cab', 'ca', 'cad') 90 """ 91 left = (side == "left" or side == "both") 92 right = (side == "right" or side == "both") 93 generators = self.semigroup_generators() 94 return lambda x: (tuple(g * x for g in generators) if left else ()) + (tuple(x * g for g in generators) if right else ()) 95 96 def __iter__(self): 97 """ 98 Returns an iterator over self 99 """ 100 from sage.combinat.backtrack import TransitiveIdeal 101 return TransitiveIdeal(self.succ_generators(side = "right"), self.semigroup_generators()).__iter__() 102 103 def ideal(self, gens, side = "both"): 104 """ 105 INPUT: 106 - gens: a list (or iterable) 107 - side: "left", "right" or "both"; defaults to "both" 108 109 Returns the left (resp. right, resp. two sided) ideal generated by gens 110 111 EXAMPLES:: 112 113 sage: S = FiniteSemigroups().example() 114 sage: list(S.ideal([S('cab')], side = "left" )) 115 ['cab', 'dcab', 'adcb', 'acb', 'bdca', 'bca', 'abdc', 116 'cadb', 'acdb', 'bacd', 'abcd', 'cbad', 'abc', 'acbd', 117 'dbac', 'dabc', 'cbda', 'bcad', 'cabd', 'dcba', 118 'bdac', 'cba', 'badc', 'bac', 'cdab', 'dacb', 'dbca', 119 'cdba', 'adbc', 'bcda'] 120 sage: list(S.ideal([S('cab')], side = "right")) 121 ['cab', 'cabd'] 122 sage: list(S.ideal([S('cab')], side = "both" )) 123 ['cab', 'dcab', 'acb', 'adcb', 'acbd', 'bdca', 'bca', 'cabd', 'abdc', 'cadb', 'acdb', 'bacd', 'abcd', 'cbad', 'abc', 'dbac', 'dabc', 'cbda', 'bcad', 'dcba', 'bdac', 'cba', 'cdab', 'bac', 'badc', 'dacb', 'dbca', 'cdba', 'adbc', 'bcda'] 124 sage: list(S.ideal([S('cab')] )) 125 ['cab', 'dcab', 'acb', 'adcb', 'acbd', 'bdca', 'bca', 'cabd', 'abdc', 'cadb', 'acdb', 'bacd', 'abcd', 'cbad', 'abc', 'dbac', 'dabc', 'cbda', 'bcad', 'dcba', 'bdac', 'cba', 'cdab', 'bac', 'badc', 'dacb', 'dbca', 'cdba', 'adbc', 'bcda'] 126 127 """ 128 from sage.combinat.backtrack import TransitiveIdeal 129 return TransitiveIdeal(self.succ_generators(side = side), gens) 130 131 def cayley_graph(self, side = "both", simple = False): 132 """ 133 134 EXAMPLES:: 135 136 sage: S = FiniteSemigroups().example(('a','b')) 137 sage: g = S.cayley_graph(side="right", simple=True) 138 sage: g.vertices() 139 ['a', 'ab', 'b', 'ba'] 140 sage: g.edges() 141 [('a', 'ab', None), ('b', 'ba', None)] 142 143 sage: g = S.cayley_graph(side="left", simple=True) 144 sage: g.vertices() 145 ['a', 'ab', 'b', 'ba'] 146 sage: g.edges() 147 [('a', 'ba', None), ('ab', 'ba', None), ('b', 'ab', None), ('ba', 'ab', None)] 148 149 sage: g = S.cayley_graph(side="both", simple=True) 150 sage: g.vertices() 151 ['a', 'ab', 'b', 'ba'] 152 sage: g.edges() 153 [('a', 'ab', None), ('a', 'ba', None), ('ab', 'ba', None), ('b', 'ab', None), ('b', 'ba', None), ('ba', 'ab', None)] 154 155 TODO: add an option to specify a subset of module generators and module operators, and a predicate to stop the iteration 156 """ 157 from sage.graphs.graph import DiGraph 158 if simple: 159 result = DiGraph() 160 else: 161 result = DiGraph(multiedges = True, loops = True) 162 result.add_vertices([x for x in self]) 163 generators = self.semigroup_generators() 164 left = (side == "left" or side == "both") 165 right = (side == "right" or side == "both") 166 def edge(source, target, label): 167 if simple: 168 return [source, target] 169 else: 170 return [source, target, label] 171 for x in self: 172 for i in generators.keys(): 173 if left: 174 result.add_edge(edge(x, generators[i]*x, (i, "left" ))) 175 if right: 176 result.add_edge(edge(x, x*generators[i], (i, "right"))) 177 return result 178 179 def twosided_ideal_graph(self, simple = False): 180 raise NotImplementedError("Please use self.cayley_graph(...)") 181 182 @cached_method 183 def j_classes(self): 184 r""" 185 Two elements $u$ and $v$ of a monoid are in the same j-class if 186 u divides v and v divides u. 187 188 This method returns all the j-classes of self, as a list of lists 189 """ 190 return self.cayley_graph(side="both", simple=True).strongly_connected_components() 191 192 @cached_method 193 def j_classes_of_idempotents(self): 194 r""" 195 Returns all idempotents of self, grouped by j-class, as a list of lists 196 """ 197 return filter(lambda l: len(l) > 0, 198 map(lambda cl: filter(attrcall('is_idempotent'), cl), 199 self.j_classes())) 200 201 @cached_method 202 def j_transversal_of_idempotents(self): 203 r""" 204 Returns a list of one idempotent per regular j-class 205 """ 206 def first_idempotent(l): 207 for x in l: 208 if x.is_idempotent(): 209 return x 210 return None 211 return filter(lambda x: not x is None, 212 map(first_idempotent, self.j_classes())) 213 214 # TODO: compute eJe, where J is the J-class of e 215 # TODO: construct the action of self on it, as a permutation group -
new file sage/categories/g_sets.py
diff --git a/sage/categories/g_sets.py b/sage/categories/g_sets.py new file mode 100644
- + 1 r""" 2 G-Sets 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from sage.categories.category import Category 22 from sage.misc.cachefunc import cached_method 23 24 ############################################################# 25 # GSets 26 # $G$-Sets play an important role in permutation groups. 27 ############################################################# 28 class GSets(Category): 29 """ 30 The category of $G$-sets, for a group $G$. 31 32 EXAMPLES: 33 sage: S = SymmetricGroup(3) 34 sage: GSets(S) 35 Category of G-sets for SymmetricGroup(3) 36 37 TESTS: 38 sage: S8 = SymmetricGroup(8) 39 sage: C = GSets(S8) 40 sage: loads(C.dumps()) == C 41 True 42 """ 43 def __init__(self, G): 44 Category.__init__(self, "G-sets") 45 self.__G = G 46 47 def __repr__(self): 48 return "Category of G-sets for %s"%self.__G 49 50 def construction(self): 51 return (self.__class__, self.__G) 52 53 @cached_method 54 def super_categories(self): 55 from sets_cat import Sets 56 return [Sets()] -
new file sage/categories/gcd_domains.py
diff --git a/sage/categories/gcd_domains.py b/sage/categories/gcd_domains.py new file mode 100644
- + 1 r""" 2 GdcDomains 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.category import Category 20 from sage.misc.cachefunc import cached_method 21 22 class GcdDomains(Category): 23 """ 24 The category of gcd domains 25 domains where gcd can be computed but where there is no guarantee of 26 factorisation into irreducibles 27 28 EXAMPLES: 29 sage: GcdDomains() 30 Category of gcd domains 31 sage: GcdDomains().super_categories() 32 [Category of integral domains] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 from sage.categories.integral_domains import IntegralDomains 39 return [IntegralDomains()] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 # gcd(x,y) 46 # lcm(x,y) 47 pass -
new file sage/categories/graded_algebras.py
diff --git a/sage/categories/graded_algebras.py b/sage/categories/graded_algebras.py new file mode 100644
- + 1 r""" 2 Graded Algebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # Nicolas M. Thiery <nthiery at users.sf.net> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from category_types import Category_over_base_ring 21 from sage.categories.all import Algebras, GradedModules 22 from sage.misc.cachefunc import cached_method 23 24 class GradedAlgebras(Category_over_base_ring): 25 """ 26 The category of graded algebras 27 28 EXAMPLES:: 29 30 sage: GradedAlgebras(ZZ) 31 Category of graded algebras over Integer Ring 32 sage: GradedAlgebras(ZZ).super_categories() 33 [Category of graded modules over Integer Ring, Category of algebras over Integer Ring] 34 35 """ 36 37 @cached_method 38 def super_categories(self): 39 R = self.base_ring() 40 return [GradedModules(R), Algebras(R)] 41 42 class ParentMethods: 43 pass 44 45 class ElementMethods: 46 pass -
new file sage/categories/graded_algebras_with_basis.py
diff --git a/sage/categories/graded_algebras_with_basis.py b/sage/categories/graded_algebras_with_basis.py new file mode 100644
- + 1 r""" 2 GradedAlgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import GradedAlgebras, GradedModulesWithBasis, AlgebrasWithBasis 21 from sage.misc.cachefunc import cached_method 22 23 class GradedAlgebrasWithBasis(Category_over_base_ring): 24 """ 25 The category of graded algebras with a distinguished basis 26 27 EXAMPLES:: 28 29 sage: GradedAlgebrasWithBasis(ZZ) 30 Category of graded algebras with basis over Integer Ring 31 sage: GradedAlgebrasWithBasis(ZZ).super_categories() 32 [Category of graded modules with basis over Integer Ring, Category of graded algebras over Integer Ring, Category of algebras with basis over Integer Ring] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [GradedModulesWithBasis(R),GradedAlgebras(R), AlgebrasWithBasis(R)] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass -
new file sage/categories/graded_bialgebras.py
diff --git a/sage/categories/graded_bialgebras.py b/sage/categories/graded_bialgebras.py new file mode 100644
- + 1 r""" 2 GradedBialgebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # Nicolas M. Thiery <nthiery at users.sf.net> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from category_types import Category_over_base_ring 21 from sage.categories.all import Bialgebras, GradedAlgebras, GradedCoalgebras 22 from sage.misc.cachefunc import cached_method 23 24 class GradedBialgebras(Category_over_base_ring): 25 """ 26 The category of bialgebras with several bases 27 28 EXAMPLES:: 29 30 sage: GradedBialgebras(ZZ) 31 Category of graded bialgebras over Integer Ring 32 sage: GradedBialgebras(ZZ).super_categories() 33 [Category of graded algebras over Integer Ring, Category of graded coalgebras over Integer Ring, Category of bialgebras over Integer Ring] 34 35 """ 36 37 @cached_method 38 def super_categories(self): 39 R = self.base_ring() 40 return [GradedAlgebras(R), GradedCoalgebras(R), Bialgebras(R)] 41 42 class ParentMethods: 43 pass 44 45 class ElementMethods: 46 pass -
new file sage/categories/graded_bialgebras_with_basis.py
diff --git a/sage/categories/graded_bialgebras_with_basis.py b/sage/categories/graded_bialgebras_with_basis.py new file mode 100644
- + 1 r""" 2 GradedBialgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import GradedBialgebras, GradedAlgebrasWithBasis, GradedCoalgebrasWithBasis 21 from sage.misc.cachefunc import cached_method 22 23 class GradedBialgebrasWithBasis(Category_over_base_ring): 24 """ 25 The category of graded bialgebras with a distinguished basis 26 27 EXAMPLES:: 28 29 sage: GradedBialgebrasWithBasis(ZZ) 30 Category of graded bialgebras with basis over Integer Ring 31 sage: GradedBialgebrasWithBasis(ZZ).super_categories() 32 [Category of graded algebras with basis over Integer Ring, Category of graded coalgebras with basis over Integer Ring, Category of graded bialgebras over Integer Ring] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [GradedAlgebrasWithBasis(R), GradedCoalgebrasWithBasis(R), GradedBialgebras(R)] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass -
new file sage/categories/graded_coalgebras.py
diff --git a/sage/categories/graded_coalgebras.py b/sage/categories/graded_coalgebras.py new file mode 100644
- + 1 r""" 2 Graded Coalgebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # Nicolas M. Thiery <nthiery at users.sf.net> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from category_types import Category_over_base_ring 21 from sage.categories.all import Coalgebras, GradedModules 22 from sage.misc.cachefunc import cached_method 23 24 class GradedCoalgebras(Category_over_base_ring): 25 """ 26 The category of graded coalgebras 27 28 EXAMPLES:: 29 30 sage: GradedCoalgebras(ZZ) 31 Category of graded coalgebras over Integer Ring 32 sage: GradedCoalgebras(ZZ).super_categories() 33 [Category of graded modules over Integer Ring, Category of coalgebras over Integer Ring] 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [GradedModules(R), Coalgebras(R)] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass -
new file sage/categories/graded_coalgebras_with_basis.py
diff --git a/sage/categories/graded_coalgebras_with_basis.py b/sage/categories/graded_coalgebras_with_basis.py new file mode 100644
- + 1 r""" 2 GradedCoalgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import GradedCoalgebras, GradedModulesWithBasis, CoalgebrasWithBasis 21 from sage.misc.cachefunc import cached_method 22 23 class GradedCoalgebrasWithBasis(Category_over_base_ring): 24 """ 25 The category of graded coalgebras with a distinguished basis 26 27 EXAMPLES:: 28 29 sage: GradedCoalgebrasWithBasis(ZZ) 30 Category of graded coalgebras with basis over Integer Ring 31 sage: GradedCoalgebrasWithBasis(ZZ).super_categories() 32 [Category of graded modules with basis over Integer Ring, Category of graded coalgebras over Integer Ring, Category of coalgebras with basis over Integer Ring] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [GradedModulesWithBasis(R), GradedCoalgebras(R), CoalgebrasWithBasis(R)] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass -
new file sage/categories/graded_hopf_algebras.py
diff --git a/sage/categories/graded_hopf_algebras.py b/sage/categories/graded_hopf_algebras.py new file mode 100644
- + 1 r""" 2 Graded Hopf algebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # Nicolas M. Thiery <nthiery at users.sf.net> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from category_types import Category_over_base_ring 21 from sage.categories.all import HopfAlgebras, GradedBialgebras 22 from sage.misc.cachefunc import cached_method 23 24 class GradedHopfAlgebras(Category_over_base_ring): 25 """ 26 The category of GradedHopf algebras with several bases 27 28 EXAMPLES:: 29 30 sage: GradedHopfAlgebras(ZZ) 31 Category of graded hopf algebras over Integer Ring 32 sage: GradedHopfAlgebras(ZZ).super_categories() 33 [Category of graded bialgebras over Integer Ring, Category of hopf algebras over Integer Ring] 34 35 """ 36 37 @cached_method 38 def super_categories(self): 39 R = self.base_ring() 40 return [GradedBialgebras(R), HopfAlgebras(R)] 41 42 class ParentMethods: 43 pass 44 45 class ElementMethods: 46 pass -
new file sage/categories/graded_hopf_algebras_with_basis.py
diff --git a/sage/categories/graded_hopf_algebras_with_basis.py b/sage/categories/graded_hopf_algebras_with_basis.py new file mode 100644
- + 1 r""" 2 GradedHopfAlgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import AbstractCategory, GradedHopfAlgebras, HopfAlgebrasWithBasis, GradedBialgebrasWithBasis 21 from sage.misc.cachefunc import cached_method 22 23 class GradedHopfAlgebrasWithBasis(Category_over_base_ring): 24 """ 25 The category of graded Hopf algebras with a distinguished basis 26 27 EXAMPLES:: 28 29 sage: GradedHopfAlgebrasWithBasis(ZZ) 30 Category of graded hopf algebras with basis over Integer Ring 31 sage: GradedHopfAlgebrasWithBasis(ZZ).super_categories() 32 [Category of graded bialgebras with basis over Integer Ring, Category of graded hopf algebras over Integer Ring, Category of hopf algebras with basis over Integer Ring] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [GradedBialgebrasWithBasis(R), GradedHopfAlgebras(R), HopfAlgebrasWithBasis(R)] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass 46 47 class AbstractCategory(AbstractCategory): 48 @cached_method 49 def super_categories(self): 50 from sage.categories.graded_hopf_algebras import GradedHopfAlgebras 51 R = self.base_category.base_ring() 52 return [GradedHopfAlgebras(R)] 53 -
new file sage/categories/graded_modules.py
diff --git a/sage/categories/graded_modules.py b/sage/categories/graded_modules.py new file mode 100644
- + 1 r""" 2 GradedModules 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # Nicolas M. Thiery <nthiery at users.sf.net> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from category_types import Category_over_base_ring 21 from sage.categories.all import Modules 22 from sage.misc.cachefunc import cached_method 23 24 class GradedModules(Category_over_base_ring): 25 """ 26 The category of graded modules 27 28 EXAMPLES: 29 sage: GradedModules(ZZ) 30 Category of graded modules over Integer Ring 31 sage: GradedModules(ZZ).super_categories() 32 [Category of modules over Integer Ring] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [Modules(R)] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass -
new file sage/categories/graded_modules_with_basis.py
diff --git a/sage/categories/graded_modules_with_basis.py b/sage/categories/graded_modules_with_basis.py new file mode 100644
- + 1 r""" 2 GradedModulesWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from category_types import Category_over_base_ring 20 from sage.categories.all import GradedModules, ModulesWithBasis 21 from sage.misc.cachefunc import cached_method 22 23 class GradedModulesWithBasis(Category_over_base_ring): 24 """ 25 The category of graded modules with a distinguished basis 26 27 EXAMPLES:: 28 29 sage: GradedModulesWithBasis(ZZ) 30 Category of graded modules with basis over Integer Ring 31 sage: GradedModulesWithBasis(ZZ).super_categories() 32 [Category of graded modules over Integer Ring, Category of modules with basis over Integer Ring] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 R = self.base_ring() 39 return [GradedModules(R), ModulesWithBasis(R)] 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass -
new file sage/categories/group_algebras.py
diff --git a/sage/categories/group_algebras.py b/sage/categories/group_algebras.py new file mode 100644
- + 1 r""" 2 GroupAlgebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from category_types import Category_over_base_ring 22 from sage.misc.cachefunc import cached_method 23 24 class GroupAlgebras(Category_over_base_ring): 25 """ 26 EXAMPLES: 27 sage: GroupAlgebras(IntegerRing()) 28 Category of group algebras over Integer Ring 29 sage: GroupAlgebras(IntegerRing()).super_categories() 30 [Category of monoid algebras over Integer Ring] 31 32 TESTS: 33 sage: C = GroupAlgebras(ZZ) 34 sage: loads(C.dumps()) == C 35 True 36 """ 37 38 @cached_method 39 def super_categories(self): 40 from monoid_algebras import MonoidAlgebras 41 R = self.base_ring() 42 return [MonoidAlgebras(R)] # TODO: could become Kac algebras / Hopf algebras -
new file sage/categories/groupoid.py
diff --git a/sage/categories/groupoid.py b/sage/categories/groupoid.py new file mode 100644
- + 1 r""" 2 PointedSets 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from sage.categories.category import Category 22 from sage.misc.cachefunc import cached_method 23 24 class Groupoid(Category): 25 """ 26 The category of groupoids, for a set (usually a group) $G$. 27 28 FIXME: 29 - Groupoid or Groupoids ? 30 - def and link with http://en.wikipedia.org/wiki/Groupoid 31 32 EXAMPLES: 33 sage: Groupoid(DihedralGroup(3)) 34 Groupoid with underlying set Dihedral group of order 6 as a permutation group 35 36 TESTS: 37 sage: S8 = SymmetricGroup(8) 38 sage: C = Groupoid(S8) 39 sage: loads(C.dumps()) == C 40 True 41 """ 42 def __init__(self, G): 43 Category.__init__(self, "Groupoid") 44 self.__G = G 45 46 def __repr__(self): 47 return "Groupoid with underlying set %s"%self.__G 48 49 def construction(self): 50 return (self.__class__, self.__G) 51 52 @cached_method 53 def super_categories(self): 54 from sets_cat import Sets 55 return [Sets()] # ??? 56 -
new file sage/categories/groups.py
diff --git a/sage/categories/groups.py b/sage/categories/groups.py new file mode 100644
- + 1 r""" 2 Groups 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.category import Category 20 from sage.categories.monoids import Monoids 21 from sage.misc.cachefunc import cached_method 22 23 class Groups(Category): 24 """ 25 The category of (multiplicative) groups, i.e. monoids with 26 inverses 27 28 29 EXAMPLES: 30 sage: Groups() 31 Category of groups 32 sage: Groups().super_categories() 33 [Category of monoids] 34 35 TESTS: 36 sage: C = Groups() 37 sage: loads(C.dumps()) == C 38 True 39 """ 40 41 @cached_method 42 def super_categories(self): 43 return [Monoids()] 44 45 class ParentMethods: 46 47 def test_inverse(self, **options): 48 tester = self.tester(**options) 49 for x in tester.some_elements(): 50 tester.assertEquals(x * ~x, self.one()) 51 tester.assertEquals(~x * x, self.one()) 52 53 class ElementMethods: 54 ## inv(x), x/y 55 pass -
new file sage/categories/hecke_modules.py
diff --git a/sage/categories/hecke_modules.py b/sage/categories/hecke_modules.py new file mode 100644
- + 1 r""" 2 Hecke modules 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from sage.categories.category_types import Category_module 22 from sage.misc.cachefunc import cached_method 23 from sage.categories.category import HomCategory 24 25 class HeckeModules(Category_module): 26 r""" 27 The category of Hecke modules. 28 29 A Hecke module is a module $M$ over the \emph{anemic} Hecke 30 algebra, i.e., the Hecke algebra generated by Hecke operators 31 $T_n$ with $n$ coprime to the level of $M$. (Every Hecke module 32 defines a level function, which is a positive integer.) The 33 reason we require that $M$ only be a module over the anemic Hecke 34 algebra is that many natural maps, e.g., degeneracy maps, 35 Atkin-Lehner operators, etc., are $\T$-module homomorphisms; but 36 they are homomorphisms over the anemic Hecke algebra. 37 38 EXAMPLES: 39 We create the category of Hecke modules over $\Q$. 40 sage: C = HeckeModules(RationalField()); C 41 Category of Hecke modules over Rational Field 42 43 TODO: check that this is what we want: 44 sage: C.super_categories() 45 [Category of modules with basis over Rational Field] 46 47 # [Category of vector spaces over Rational Field] 48 49 Note that the base ring can be an arbitrary commutative ring. 50 sage: HeckeModules(IntegerRing()) 51 Category of Hecke modules over Integer Ring 52 sage: HeckeModules(FiniteField(5)) 53 Category of Hecke modules over Finite Field of size 5 54 55 The base ring doesn't have to be a principal ideal domain. 56 sage: HeckeModules(PolynomialRing(IntegerRing(), 'x')) 57 Category of Hecke modules over Univariate Polynomial Ring in x over Integer Ring 58 59 TESTS: 60 sage: C = HeckeModules(ZZ) 61 sage: loads(C.dumps()) == C 62 True 63 """ 64 def __init__(self, R): 65 from commutative_rings import CommutativeRings 66 if R not in CommutativeRings(): 67 raise TypeError, "R (=%s) must be a commutative ring"%R 68 Category_module.__init__(self, R, "Hecke modules") 69 70 @cached_method 71 def super_categories(self): 72 from sage.categories.all import ModulesWithBasis 73 R = self.base_ring() 74 return [ModulesWithBasis(R)] 75 76 class HomCategory(HomCategory): 77 def extra_super_categories(self): 78 return [] # FIXME: what category structure is there on Homsets of hecke modules? 79 80 import sage.modular.hecke.homspace 81 class ParentMethods(sage.modular.hecke.homspace.HeckeModuleHomspace): 82 pass -
new file sage/categories/hopf_algebras.py
diff --git a/sage/categories/hopf_algebras.py b/sage/categories/hopf_algebras.py new file mode 100644
- + 1 r""" 2 HopfAlgebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # Nicolas M. Thiery <nthiery at users.sf.net> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from category_types import Category_over_base_ring 21 from sage.categories.all import Category, TensorialCategory, TensorCategory, DualityCategory, Bialgebras 22 from sage.categories.tensor import tensor 23 from sage.misc.cachefunc import cached_method 24 from sage.misc.lazy_attribute import lazy_attribute 25 26 class HopfAlgebras(Category_over_base_ring, TensorialCategory, DualityCategory): 27 """ 28 The category of Hopf algebras 29 30 EXAMPLES:: 31 32 sage: HopfAlgebras(QQ) 33 Category of hopf algebras over Rational Field 34 sage: HopfAlgebras(QQ).super_categories() 35 [Category of bialgebras over Rational Field] 36 """ 37 38 @cached_method 39 def super_categories(self): 40 R = self.base_ring() 41 return [Bialgebras(R)] 42 43 def dual(self): # The category of Hopf Algebra is self dual 44 self 45 46 class ElementMethods: 47 def antipode(self): 48 return self.parent().antipode(self) 49 # Variant: delegates to the overloading mechanism 50 # result not guaranted to be in self 51 # This choice should be done consistently with coproduct, ... 52 # return operator.antipode(self) 53 54 class ParentMethods: 55 def __setup__(self): # Check the conventions for _setup_ or __setup__ 56 if self.implements("antipode"): 57 coercion.declare(operator.antipode, [self], self.antipode) 58 59 @lazy_attribute 60 def antipode(self): 61 # delegates to the overloading mechanism but 62 # guarantees that the result is in self 63 compose(self, operator.antipode, domain=self) 64 65 class Morphism(Category): 66 """ 67 The category of Hopf algebra morphisms 68 """ 69 pass 70 71 72 class TensorCategory(TensorCategory): 73 """ 74 The category of Hopf algebras constructed by tensor product of Hopf algebras 75 """ 76 @cached_method 77 def super_categories(self): 78 return [HopfAlgebras(self.base_category.base_ring())] 79 80 class ParentMethods: 81 """ 82 implements operations on tensor products of Hopf algebras 83 """ 84 @lazy_attribute 85 def antipode(self): 86 return tensor([module.antipode for module in self.modules]) 87 88 class ElementMethods: 89 """ 90 implements operations on elements of tensor products of Hopf algebras 91 """ 92 pass 93 94 class DualCategory(Category_over_base_ring): 95 """ 96 The category of Hopf algebras constructed as dual of a Hopf algebra 97 """ 98 99 class ParentMethods: 100 """ 101 implements operations on the dual of a Hopf algebra 102 """ 103 @lazy_attribute 104 def antipode(self): 105 self.dual().antipode.dual() # Check that this is the correct formula -
new file sage/categories/hopf_algebras_with_basis.py
diff --git a/sage/categories/hopf_algebras_with_basis.py b/sage/categories/hopf_algebras_with_basis.py new file mode 100644
- + 1 r""" 2 HopfAlgebrasWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Nicolas Thiery 6 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 7 # 8 # Distributed under the terms of the GNU General Public License (GPL) 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 # General Public License for more details. 14 # 15 # The full text of the GPL is available at: 16 # 17 # http://www.gnu.org/licenses/ 18 #****************************************************************************** 19 20 from sage.categories.category_types import Category_over_base_ring 21 from sage.categories.all import Category, TensorialCategory, TensorCategory, DualityCategory, HopfAlgebras, BialgebrasWithBasis, End 22 from sage.misc.lazy_attribute import lazy_attribute 23 from sage.misc.cachefunc import cached_method 24 25 class HopfAlgebrasWithBasis(Category_over_base_ring, TensorialCategory, DualityCategory): 26 """ 27 The category of Hopf algebras with a distinguished basis 28 29 EXAMPLES:: 30 31 sage: C = HopfAlgebrasWithBasis(QQ) 32 sage: C 33 Category of hopf algebras with basis over Rational Field 34 sage: C.super_categories() 35 [Category of bialgebras with basis over Rational Field, Category of hopf algebras over Rational Field] 36 37 We now show how to use a simple hopf algebra, namely the group algebra of the dihedral group 38 (see also AlgebrasWithBasis):: 39 40 sage: A = C.example(); A 41 The Hopf algebra of the Dihedral group of order 6 as a permutation group over Rational Field 42 sage: A.__custom_name = "A" 43 sage: A.category() 44 Category of hopf algebras with basis over Rational Field 45 46 sage: A.one_basis() 47 () 48 sage: A.one() 49 B[()] 50 51 sage: A.base_ring() 52 Rational Field 53 sage: A.basis().keys() 54 Dihedral group of order 6 as a permutation group 55 56 sage: [a,b] = A.algebra_generators() 57 sage: a, b 58 (B[(1,2,3)], B[(1,3)]) 59 sage: a^3, b^2 60 (B[()], B[()]) 61 sage: a*b 62 B[(1,2)] 63 64 sage: A.product # todo: not quite ... 65 Generic endomorphism of A 66 sage: A.product(b,b) 67 B[()] 68 69 sage: A.zero().coproduct() 70 0 71 sage: A.zero().coproduct().parent() 72 A # A 73 sage: a.coproduct() 74 B[(1,2,3)] # B[(1,2,3)] 75 76 sage: A.check(verbose=True) 77 running test_additive_associativity ... done 78 running test_an_element ... done 79 running test_associativity ... done 80 running test_element_pickling ... done 81 running test_not_implemented_methods ... done 82 running test_one ... done 83 running test_pickling ... done 84 running test_prod ... done 85 running test_product ... done 86 running test_some_elements ... done 87 sage: A.__class__ 88 <class 'sage.categories.examples.hopf_algebras_with_basis.MyGroupAlgebra_with_category'> 89 sage: A.element_class 90 <class 'sage.combinat.free_module.MyGroupAlgebra_with_category.element_class'> 91 92 Let us look at the code for implementing A:: 93 94 sage: A?? # todo: not implemented 95 96 TESTS:: 97 98 sage: loads(dumps(A)) is A 99 True 100 """ 101 102 @cached_method 103 def super_categories(self): 104 R = self.base_ring() 105 return [BialgebrasWithBasis(R), HopfAlgebras(R)] 106 107 def example(self, G = None): 108 """ 109 Returns an example of algebra with basis:: 110 111 sage: HopfAlgebrasWithBasis(QQ[x]).example() 112 The Hopf algebra of the Dihedral group of order 6 as a permutation group over Univariate Polynomial Ring in x over Rational Field 113 114 An other group can be specified as optional argument:: 115 116 sage: HopfAlgebrasWithBasis(QQ).example(SymmetricGroup(4)) 117 The Hopf algebra of the SymmetricGroup(4) over Rational Field 118 119 """ 120 from sage.categories.examples.hopf_algebras_with_basis import MyGroupAlgebra 121 from sage.groups.perm_gps.permgroup_named import DihedralGroup 122 if G is None: 123 G = DihedralGroup(3) 124 return MyGroupAlgebra(self.base_ring(), G) 125 126 class ParentMethods: 127 128 @lazy_attribute 129 def antipode(self, existence_only=False): 130 if hasattr(self, "antipode_on_basis"): 131 # Should give the information that this is an anti-morphism of algebra 132 return self._module_morphism(self.antipode_on_basis, codomain = self) 133 134 class ElementMethods: 135 pass 136 137 class TensorCategory(TensorCategory): 138 """ 139 The category of hopf algebras with basis constructed by tensor product of hopf algebras with basis 140 """ 141 142 @cached_method 143 def super_categories(self): 144 return [HopfAlgebrasWithBasis(self.base_category.base_ring())] 145 146 class ParentMethods: 147 """ 148 implements operations on tensor products of modules with basis 149 """ 150 # todo: antipode 151 pass 152 153 class ElementMethods: 154 """ 155 implements operations on elements of tensor products of Hopf algebras 156 """ 157 pass 158 -
new file sage/categories/infinite_enumerated_sets.py
diff --git a/sage/categories/infinite_enumerated_sets.py b/sage/categories/infinite_enumerated_sets.py new file mode 100644
- + 1 r""" 2 Infinite Enumerated Sets 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2009 Florent Hivert <Florent.Hivert@univ-rouen.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 20 from category_types import Category 21 from sage.misc.cachefunc import cached_method 22 from sage.categories.enumerated_sets import EnumeratedSets 23 24 ################################################################# 25 class InfiniteEnumeratedSets(Category): 26 """ 27 The category of infinite enumerated sets 28 29 An infinte enumerated sets is a countable sets together with a canonical 30 enumeration of its elements; It is a subcategory of ``EnumeratedSet()``. 31 32 EXAMPLES:: 33 34 sage: InfiniteEnumeratedSets() 35 Category of infinite enumerated sets 36 sage: InfiniteEnumeratedSets().super_categories() 37 [Category of enumerated sets] 38 sage: InfiniteEnumeratedSets().all_super_categories() 39 [Category of infinite enumerated sets, 40 Category of enumerated sets, 41 Category of sets, 42 Category of objects] 43 44 TESTS:: 45 46 sage: C = InfiniteEnumeratedSets() 47 sage: loads(C.dumps()) == C 48 True 49 """ 50 @cached_method 51 def super_categories(self): 52 return [EnumeratedSets()] 53 54 def example(self): 55 """ 56 The simplest example of infinite enumerated sets: the non-negative 57 integers. 58 59 EXAMPLES:: 60 61 sage: InfiniteEnumeratedSets().example() 62 Set of non negative integers 63 """ 64 from sage.categories.examples.infinite_enumerated_sets import NonNegativeIntegers 65 return NonNegativeIntegers() 66 67 class ParentMethods: 68 def cardinality(self): 69 from sage.rings.infinity import infinity 70 """ 71 Counts the elements of the enumerated set. 72 73 EXAMPLES:: 74 75 sage: NN = InfiniteEnumeratedSets().example() 76 sage: NN.cardinality() 77 +Infinity 78 """ 79 return infinity 80 81 def random_element(self): 82 """ 83 Returns an error since self is an infinite enumerated set. 84 85 EXAMPLES:: 86 87 sage: NN = InfiniteEnumeratedSets().example() 88 sage: NN.random_element() 89 Traceback (most recent call last): 90 ... 91 NotImplementedError: infinite set 92 """ 93 raise NotImplementedError, "infinite set" 94 95 def list(self): 96 """ 97 Returns an error since self is an infinite enumerated set. 98 99 EXAMPLES:: 100 101 sage: NN = InfiniteEnumeratedSets().example() 102 sage: NN.list() 103 Traceback (most recent call last): 104 ... 105 NotImplementedError: infinite list 106 """ 107 raise NotImplementedError, "infinite list" 108 _list_default = list # needed by the check system. 109 110 # The following function overload the one 111 max_test_enumerated_set_loop=100 # number of element tested in self 112 def test_enumerated_set_iter_cardinality(self, **options): 113 tester = self.tester(**options) 114 """ 115 Check the coherency between methods ``cardinality`` and 116 ``__iter__``. Automagically called by ``check()`` 117 118 For infinite enumerated sets: 119 120 * ``cardinality`` is supposed to return ``Infinity`` 121 122 * ``list`` is supposed to raise a ``NotImplementedError``. 123 124 EXAMPLE:: 125 126 sage: NN = InfiniteEnumeratedSets().example() 127 sage: NN.test_enumerated_set_iter_cardinality() 128 """ 129 from sage.rings.infinity import infinity 130 tester.assertEqual(self.cardinality(), infinity) 131 tester.assertRaises(NotImplementedError, self.list) 132 133 class ElementMethods: 134 pass -
new file sage/categories/integral_domains.py
diff --git a/sage/categories/integral_domains.py b/sage/categories/integral_domains.py new file mode 100644
- + 1 r""" 2 IntegralDomains 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.category import Category 20 from sage.categories.basic import CommutativeRings, EntireRings 21 from sage.misc.cachefunc import cached_method 22 23 class IntegralDomains(Category): 24 """ 25 The category of integral domains 26 commutative rings with no zero divisors 27 28 EXAMPLES: 29 sage: IntegralDomains() 30 Category of integral domains 31 sage: IntegralDomains().super_categories() 32 [Category of commutative rings, Category of entire rings] 33 34 """ 35 36 @cached_method 37 def super_categories(self): 38 from sage.categories.basic import CommutativeRings, EntireRings 39 return [CommutativeRings(), EntireRings()] # TODO: Algebras(R) ? 40 41 class ParentMethods: 42 pass 43 44 class ElementMethods: 45 pass -
new file sage/categories/left_modules.py
diff --git a/sage/categories/left_modules.py b/sage/categories/left_modules.py new file mode 100644
- + 1 r""" 2 LeftModules 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.all import AbelianGroups 20 from category_types import Category_over_base_ring 21 from sage.misc.cachefunc import cached_method 22 23 #?class LeftModules(Category_over_base_rng): 24 class LeftModules(Category_over_base_ring): 25 """ 26 The category of left modules 27 left modules over an rng (ring not necessarily with unit), i.e. 28 an abelian group with left multiplation by elements of the rng 29 30 EXAMPLES: 31 sage: LeftModules(ZZ) 32 Category of left modules over Integer Ring 33 sage: LeftModules(ZZ).super_categories() 34 [Category of abelian groups] 35 36 """ 37 38 @cached_method 39 def super_categories(self): 40 return [AbelianGroups()] 41 42 class ParentMethods: 43 pass 44 45 class ElementMethods: 46 ## r * x 47 pass -
new file sage/categories/matrix_algebras.py
diff --git a/sage/categories/matrix_algebras.py b/sage/categories/matrix_algebras.py new file mode 100644
- + 1 r""" 2 MatrixAlgebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from category_types import Category_over_base_ring 22 from sage.misc.cachefunc import cached_method 23 24 class MatrixAlgebras(Category_over_base_ring): 25 """ 26 The category of matrix algebras over a field. 27 28 EXAMPLES: 29 sage: MatrixAlgebras(RationalField()) 30 Category of matrix algebras over Rational Field 31 32 TESTS: 33 sage: C = MatrixAlgebras(ZZ) 34 sage: loads(C.dumps()) == C 35 True 36 """ 37 38 @cached_method 39 def super_categories(self): 40 from algebras import Algebras 41 R = self.base_ring() 42 return [Algebras(R)] -
new file sage/categories/modular_abelian_varieties.py
diff --git a/sage/categories/modular_abelian_varieties.py b/sage/categories/modular_abelian_varieties.py new file mode 100644
- + 1 r""" 2 ModularAbelianVarieties 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # The full text of the GPL is available at: 17 # 18 # http://www.gnu.org/licenses/ 19 #****************************************************************************** 20 21 from category_types import Category_over_base 22 from sage.misc.cachefunc import cached_method 23 24 class ModularAbelianVarieties(Category_over_base): 25 """ 26 The category of modular abelian varieties over a given field. 27 28 EXAMPLES: 29 sage: ModularAbelianVarieties(QQ) 30 Category of modular abelian varieties over Rational Field 31 32 TESTS: 33 sage: C = ModularAbelianVarieties(QQ) 34 sage: loads(C.dumps()) == C 35 True 36 """ 37 def __init__(self, Y): 38 assert Y.is_field() 39 Category_over_base.__init__(self, Y) 40 41 def base_field(self): 42 return self.base() 43 44 @cached_method 45 def super_categories(self): 46 from sets_cat import Sets 47 return [Sets()] # FIXME 48 49 def _repr_(self): 50 return "Category of modular abelian varieties over %s"%self.base_field() 51 -
new file sage/categories/modules.py
diff --git a/sage/categories/modules.py b/sage/categories/modules.py new file mode 100644
- + 1 r""" 2 Modules 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.all import Bimodules, HomCategory 20 from category_types import Category_over_base_ring 21 from sage.misc.lazy_attribute import lazy_attribute 22 from sage.misc.cachefunc import cached_method 23 24 class Modules(Category_over_base_ring): 25 """ 26 The category of all modules over a base ring. 27 28 R-left and R-right modules 29 modules over a commutative ring 30 ## r*(x*s) = (r*x)*s 31 32 EXAMPLES: 33 sage: Modules(RationalField()) 34 Category of modules over Rational Field 35 36 sage: Modules(Integers(9)) 37 Category of modules over Ring of integers modulo 9 38 39 sage: RingModules(Integers(9)).super_categories() 40 [Category of bimodules over Ring of integers modulo 9 on the left and Ring of integers modulo 9 on the right] 41 sage: RingModules(Integers(9)).all_super_categories() 42 [Category of modules over Ring of integers modulo 9, 43 Category of bimodules over Ring of integers modulo 9 on the left and Ring of integers modulo 9 on the right, 44 Category of left modules over Ring of integers modulo 9, 45 Category of right modules over Ring of integers modulo 9, 46 Category of abelian groups, 47 Category of abelian monoids, 48 Category of abelian semigroups, 49 Category of sets, 50 Category of objects] 51 52 sage: Modules(ZZ).super_categories() 53 [Category of bimodules over Integer Ring on the left and Integer Ring on the right] 54 55 TESTS: 56 sage: C = RingModules(ZZ) 57 sage: loads(dumps(C)) == C 58 True 59 60 """ 61 62 @cached_method 63 def super_categories(self): 64 R = self.base_ring() 65 return [Bimodules(R,R)] 66 67 class ParentMethods: 68 pass 69 70 class ElementMethods: 71 def __mul__(left, right): 72 from sage.structure.element import get_coercion_model 73 import operator 74 return get_coercion_model().bin_op(left, right, operator.mul) 75 76 def __rmul__(right, left): 77 from sage.structure.element import get_coercion_model 78 import operator 79 return get_coercion_model().bin_op(left, right, operator.mul) 80 81 82 class HomCategory(HomCategory): 83 """ 84 The category of homomorphisms sets Hom(X,Y) for X, Y modules 85 """ 86 87 def extra_super_categories(self): 88 return [Modules(self.base_category.base_ring())] 89 90 class ParentMethods: 91 @cached_method 92 def zero(self): 93 return self(lambda x: self.codomain().zero()) 94 95 class EndCategory(HomCategory): 96 """ 97 The category of endomorphisms sets End(X) for X module 98 """ 99 100 def extra_super_categories(self): 101 return [Algebras(self.base_category.base_ring())] -
new file sage/categories/modules_with_basis.py
diff --git a/sage/categories/modules_with_basis.py b/sage/categories/modules_with_basis.py new file mode 100644
- + 1 r""" 2 ModulesWithBasis 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr> 6 # 7 # Distributed under the terms of the GNU General Public License (GPL) 8 # 9 # This code is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # General Public License for more details. 13 # 14 # The full text of the GPL is available at: 15 # 16 # http://www.gnu.org/licenses/ 17 #****************************************************************************** 18 19 from sage.categories.all import Modules, Rings, Fields, VectorSpaces, HomCategory, Homset, AbelianCategory, DirectSumCategory, TensorialCategory, TensorCategory 20 from category_types import Category_over_base_ring 21 from sage.misc.lazy_attribute import lazy_attribute 22 from sage.misc.cachefunc import cached_method 23 from sage.structure.element import ModuleElement 24 from sage.categories.morphism import SetMorphism, Morphism 25 from sage.categories.homset import Hom 26 27 28 class ModulesWithBasis(Category_over_base_ring, AbelianCategory, TensorialCategory): #, DualityCategory): 29 """ 30 The category of modules with a distinguished basis 31 32 EXAMPLES: 33 sage: ModulesWithBasis(ZZ) 34 Category of modules with basis over Integer Ring 35 sage: ModulesWithBasis(ZZ).super_categories() 36 [Category of modules over Integer Ring] 37 38 If the base ring is actually a field, this is a subcategory of 39 the category of abstract vector fields: 40 41 sage: ModulesWithBasis(RationalField()).super_categories() 42 [Category of vector spaces over Rational Field] 43 44 Let $X$ and $Y$ be two modules with basis. We can build $Hom(X,Y)$: 45 sage: X = CombinatorialFreeModule(QQ, [1,2]); X.__custom_name = "X" 46 sage: Y = CombinatorialFreeModule(QQ, [3,4]); Y.__custom_name = "Y" 47 sage: H = Hom(X, Y); H 48 Set of Morphisms from X to Y in Category of modules with basis over Rational Field 49 50 The simplest morphism is the zero map: 51 52 sage: H.zero() # todo: move this test into module once we have an example 53 Generic morphism: 54 From: X 55 To: Y 56 57 which we can apply to elements of X: 58 sage: x = X.term(1) + 3 * X.term(2) 59 sage: H.zero()(x) 60 0 61 62 TESTS: 63 sage: f = H.zero().on_basis() 64 sage: f(1) 65 0 66 sage: f(2) 67 0 68 69 EXAMPLES: 70 We now construct a more interesting morphism by extending a 71 function by linearity: 72 73 sage: phi = H(on_basis = lambda i: Y.term(i+2)); phi 74 Generic morphism: 75 From: X 76 To: Y 77 sage: phi(x) 78 B[3] + 3*B[4] 79 80 We can retrieve the function acting on indices of the basis: 81 sage: f = phi.on_basis() 82 sage: f(1), f(2) 83 (B[3], B[4]) 84 85 $Hom(X,Y)$ has a natural module structure (except for the zero, 86 the operations are not yet implemented though). However since 87 the dimension is not necessarily finite, it is not a module with 88 basis; but see FiniteDimensionalModulesWithBasis and 89 GradedModulesWithBasis: 90 91 sage: H in ModulesWithBasis(QQ), H in Modules(QQ) 92 (False, True) 93 94 Some more playing around with categories and higher order homsets: 95 96 sage: H.category() 97 Category of hom sets of Category of modules with basis over Rational Field 98 sage: Hom(H, H).category() 99 Category of hom sets of Category of modules over Rational Field 100 101 # TODO: End(X) is an algebra 102 103 TESTS: 104 sage: C = ModulesWithBasis(ZZ) 105 sage: loads(C.dumps()) == C 106 True 107 """ 108 109 @cached_method 110 def super_categories(self): 111 R = self.base_ring() 112 if R in Fields(): 113 return [VectorSpaces(R)] 114 else: 115 return [Modules(R)] 116 117 def __call__(self, x): 118 try: 119 M = x.free_module() 120 if M.base_ring() != self.base_ring(): 121 M = M.change_ring(self.base_ring()) 122 except (TypeError, AttributeError), msg: 123 raise TypeError, "%s\nunable to coerce x (=%s) into %s"%(msg,x,self) 124 return M 125 126 def is_abelian(self): 127 return self.base_ring().is_field() 128 129 # TODO: find something better to get this inheritance from TensorialCategory.Element 130 class ParentMethods(TensorialCategory.ParentMethods, AbelianCategory.ParentMethods): 131 def module_morphism(self, on_basis = None, diagonal = None, **keywords): 132 """ 133 Constructs functions by linearity 134 135 INPUT: 136 - self: a parent `X` in ModulesWithBasis(R), with basis `x` indexed by `I` 137 - codomain: the codomain `Y` of f: defaults to `f.codomain if the later is defined 138 - zero: the zero of the codomain; defaults to codomain.zero() or 0 if codomain is not specified 139 - position: a non negative integer; defaults to 0 140 - on_basis: a function `f` which accepts elements of `I` 141 as position-th argument and returns elements of `Y` 142 - diagonal: a function `d` from `I` to `R` 143 - category: a category. By default, this is 144 ``ModulesWithBasis(R)`` if `Y` is in this category, and 145 otherwise this lets `Hom(X,Y)` decide 146 147 Exactly one of ``on_basis`` and ``diagonal`` options should be specified. 148 149 With the ``on_basis`` option, this returns a function `g` 150 obtained by extending `f` by linearity on the position-th 151 positional argument. For example, for position == 1 and a 152 ternary function `f`, and denoting by x_i the basis of 153 `X`, one has: 154 155 `g(a, \sum \lambda_i x_i, c) = \sum \lambda_i f(a, i, c)` 156 157 EXAMPLES:: 158 sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") 159 sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") 160 sage: phi = X.module_morphism(lambda i: Y.term(i) + 2*Y.term(i+1), codomain = Y) 161 sage: phi 162 Generic morphism: 163 From: X 164 To: Y 165 sage: x = X.basis() 166 sage: phi(x[1] + x[3]) 167 B[1] + 2*B[2] + B[3] + 2*B[4] 168 169 With the ``diagonal`` argument, this returns the module morphism `g` such that: 170 171 `g(x_i) = d(i) y_i` 172 173 This assumes that the respective bases `x` and `y` of `X` 174 and `Y` have the same index set `I`. 175 176 177 Caveat: the returned element is in ``Hom(codomain, domain, 178 category``). This is only correct for unary functions. 179 180 Todo: should codomain be self by default in the diagonal case? 181 182 """ 183 if diagonal is not None: 184 return DiagonalModuleMorphism(diagonal = diagonal, domain = self, **keywords) 185 elif on_basis is not None: 186 return ModuleMorphismByLinearity(on_basis = on_basis, domain = self, **keywords) 187 else: 188 raise ValueError("module morphism requires either on_basis or diagonal argument") 189 190 _module_morphism = module_morphism 191 192 # TODO: find something better to get this inheritance from TensorialCategory.Element 193 class ElementMethods(TensorialCategory.ElementMethods, AbelianCategory.ElementMethods): 194 195 def _neg_(self): 196 """ 197 Default implementation of negation by trying to multiply by -1. 198 """ 199 return self._lmul_(-self.parent()(1), self) # FIXME: use .parent().one() 200 201 class HomCategory(HomCategory): 202 """ 203 The category of homomorphisms sets Hom(X,Y) for X, Y modules with basis 204 """ 205 206 class ParentMethods: #(sage.modules.free_module_homspace.FreeModuleHomspace): # Only works for plain FreeModule's 207 """ 208 Abstract class for hom sets 209 """ 210 211 def __call__(self, on_basis = None, *args, **options): 212 if on_basis is not None: 213 args = (self.domain()._module_morphism(on_basis, codomain = self.codomain()),) + args 214 h = Homset.__call__(self, *args, **options) 215 if on_basis is not None: 216 h._on_basis = on_basis 217 return h 218 219 # Temporary hack 220 __call_on_basis__ = __call__ 221 222 @lazy_attribute 223 def element_class_set_morphism(self): 224 return self.__make_element_class__(SetMorphism, "%s.element_class"%self.__class__.__name__, inherit = True) 225 226 class ElementMethods: 227 """ 228 Abstract class for morphisms of modules with basis 229 """ 230 def on_basis(self): # or lazy_attribute? 231 if not hasattr(self, "_on_basis"): 232 term = self.domain().term 233 self._on_basis = lambda t: self(term(t)) 234 return self._on_basis 235 236 237 class DirectSumCategory(DirectSumCategory): 238 """ 239 The category of modules with basis constructed by direct sums of modules with basis 240 """ 241 @cached_method 242 def super_categories(self): 243 return [ModulesWithBasis(self.base_category.base_ring())] 244 245 246 class ParentMethods: 247 # Will there be an super category with direct sum? 248 def _an_element_(self): 249 return direct_sum([module.an_element() for module in self.modules]) 250 251 class TensorCategory(TensorCategory): 252 """ 253 The category of modules with basis constructed by tensor product of modules with basis 254 """ 255 @cached_method 256 def super_categories(self): 257 return [ModulesWithBasis(self.base_category.base_ring())] 258 259 class ParentMethods: 260 """ 261 implements operations on tensor products of modules with basis 262 """ 263 pass 264 265 class ElementMethods: 266 """ 267 implements operations on elements of tensor products of Hopf algebras 268 """ 269 pass 270 271 class ModuleMorphismByLinearity(Morphism): 272 """ 273 A class for module morphisms obtained by extending a function by linearity 274 275 EXAMPLES:: 276 sage: X = CombinatorialFreeModule(QQ, [1,2]) 277 sage: phi = sage.categories.modules_with_basis.ModuleMorphismByLinearity(X, QQ, zero = 0, codomain = QQ) 278 sage: phi 279 Generic morphism: 280 From: X 281 To: Rational Field 282 283 TESTS:: 284 sage: loads(dumps(phi)) 285 Generic morphism: 286 From: X 287 To: Rational Field 288 sage: loads(dumps(phi)) == phi # Todo: not implemented 289 True 290 291 """ 292 293 294 def __init__(self, domain, on_basis = None, position = 0, zero = None, codomain = None, category = None): 295 """ 296 Constructs a module morphism by linearity 297 298 INPUT: 299 - domain: a parent in ModulesWithBasis(...) 300 - codomain: a parent in Modules(...); defaults to f.codomain() if the later is defined 301 - position: a non negative integer; defaults to 0 302 - on_basis: a function which accepts indices of the basis of domain as position-th argument 303 - zero: the zero of the codomain; defaults to codomain.zero() or 0 if codomain is not specified 304 305 """ 306 if codomain is None and hasattr(on_basis, 'codomain'): 307 codomain = on_basis.codomain() 308 if zero is None: 309 if codomain is not None: 310 zero = codomain.zero() 311 else: 312 zero = 0 313 if category is None and codomain is not None and codomain.category().is_subcategory(ModulesWithBasis(domain.base_ring())): 314 category = ModulesWithBasis(domain.base_ring()) 315 if codomain is not None: 316 parent = Hom(domain, codomain, category = category) 317 Morphism.__init__(self, parent) 318 self._zero = zero 319 self.position = position 320 if on_basis is not None: 321 self._on_basis = on_basis 322 323 def on_basis(self): 324 return self._on_basis 325 326 def __call__(self, *args): 327 before = args[0:self.position] 328 after = args[self.position+1:len(args)] 329 x = args[self.position] 330 assert(x.parent() is self.domain()) 331 return sum([self._on_basis(*(before+(index,)+after))._lmul_(coeff) for (index, coeff) in args[self.position]], self._zero) 332 333 # As per the specs of Map, we should in fact implement _call_ but 334 # Map.__call__ does strict type checking which prevents 335 # multi-parameter module morphisms 336 # To be cleaned up 337 _call_ = __call__ 338 339 class DiagonalModuleMorphism(ModuleMorphismByLinearity): 340 """ 341 A class for diagonal module morphisms. 342 343 See :meth:`module_morphism` of ModulesWithBasis 344 345 EXAMPLES:: 346 sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") 347 sage: phi = X.module_morphism(diagonal = factorial, codomain = X) 348 349 TESTS:: 350 sage: phi.__class__ 351 <class 'sage.categories.modules_with_basis.DiagonalModuleMorphism'> 352 sage: loads(dumps(phi)) 353 Generic endomorphism of X 354 sage: loads(dumps(phi)) == phi # Todo: not implemented 355 True 356 357 Todo: 358 - implement an optimized _call_ function 359 - generalize to a mapcoeffs 360 - generalize to a mapterms 361 362 """ 363 364 def __init__(self, diagonal, domain, codomain = None, category = None): 365 """ 366 INPUT: 367 - domain, codomain: two modules with basis `F` and `G` 368 - diagonal: a function `d` 369 370 Assumptions: 371 - `F` and `G` have the same base ring `R` 372 - Their respective bases `f` and `g` have the same index set `I` 373 - `d` is a function `I\mapsto R` 374 375 Returns the diagonal module morphism from F to G which maps 376 `f_\lambda` to `d(\lambda) g_\lambda`. 377 378 By default, codomain is currently assumed to be domain (Todo: 379 make a consistent choice with ModuleMorphism) 380 """ 381 assert codomain is not None 382 assert domain.basis().keys() == codomain.basis().keys() 383 assert domain.base_ring() == codomain.base_ring() 384 if category is None: 385 category = ModulesWithBasis(domain.base_ring()) 386 ModuleMorphismByLinearity.__init__(self, domain = domain, codomain = codomain, category = category) 387 self._diagonal = diagonal 388 389 def _on_basis(self, i): 390 """ 391 Returns the image by self of the basis element indexed by i 392 393 TESTS:: 394 sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() 395 sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("Y"); y = Y.basis() 396 sage: phi = X.module_morphism(diagonal = factorial, codomain = X) 397 sage: phi._on_basis(3) 398 6*B[3] 399 """ 400 return self.codomain().monomial(i, self._diagonal(i)) 401 402 def __invert__(self): 403 """ 404 Returns the inverse diagonal morphism 405 406 sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() 407 sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("Y"); y = Y.basis() 408 sage: phi = X.module_morphism(diagonal = factorial, codomain = X) 409 sage: phi_inv = ~phi 410 sage: phi_inv 411 Generic endomorphism of Y 412 sage: phi_inv(y[3]) 413 1/6*B[3] 414 415 Caveat: this inverse morphism is only well defined if 416 `d(\lambda)` is always invertible in the base ring. This is 417 condition is *not* tested for, so using an ill defined inverse 418 morphism will trigger arithmetic errors. 419 """ 420 return self.__class__( 421 pointwise_inverse_function(self._diagonal), 422 domain = self.codomain(), codomain = self.domain(), category = self.category_for()) 423 424 425 def pointwise_inverse_function(f): 426 """ 427 INPUT: 428 - f: a function 429 430 Returns the function (...) -> 1 / f(...) 431 432 EXAMPLES: 433 sage: from sage.categories.modules_with_basis import pointwise_inverse_function 434 sage: def f(x): return x 435 ... 436 sage: g = pointwise_inverse_function(f) 437 sage: g(1), g(2), g(3) 438 (1, 1/2, 1/3) 439 440 pointwise_inverse_function is an involution: 441 442 sage: f is pointwise_inverse_function(g) 443 True 444 445 Todo: this has nothing to do here!!! Should there be a library for 446 pointwise operations on functions somewhere in Sage? 447 448 """ 449 if hasattr(f, "pointwise_inverse"): 450 return f.pointwise_inverse() 451 else: 452 return PointwiseInverseFunction(f) 453 454 from sage.structure.sage_object import SageObject 455 class PointwiseInverseFunction(SageObject): 456 """ 457 A class for point wise inverse functions 458 459 EXAMPLES: 460 sage: from sage.categories.modules_with_basis import PointwiseInverseFunction 461 sage: f = PointwiseInverseFunction(factorial) 462 sage: f(0), f(1), f(2), f(3) 463 (1, 1, 1/2, 1/6) 464 """ 465 466 def __eq__(self, other): 467 """ 468 TESTS: 469 sage: from sage.categories.modules_with_basis import PointwiseInverseFunction 470 sage: f = PointwiseInverseFunction(factorial) 471 sage: g = PointwiseInverseFunction(factorial) 472 sage: f is g 473 False 474 sage: f == g 475 True 476 """ 477 return self.__class__ is other.__class__ and self.__dict__ == other.__dict__ 478 479 def __init__(self, f): 480 """ 481 TESTS: 482 sage: from sage.categories.modules_with_basis import PointwiseInverseFunction 483 sage: f = PointwiseInverseFunction(factorial) 484 sage: f(0), f(1), f(2), f(3) 485 (1, 1, 1/2, 1/6) 486 sage: loads(dumps(f)) == f 487 True 488 """ 489 self._pointwise_inverse = f 490 491 def __call__(self, *args): 492 """ 493 TESTS: 494 sage: from sage.categories.modules_with_basis import PointwiseInverseFunction 495 sage: g = PointwiseInverseFunction(operator.mul) 496 sage: g(5,7) 497 1/35 498 """ 499 return ~(self._pointwise_inverse(*args)) 500 501 def pointwise_inverse(self): 502 """ 503 TESTS: 504 sage: from sage.categories.modules_with_basis import PointwiseInverseFunction 505 sage: g = PointwiseInverseFunction(operator.mul) 506 sage: g.pointwise_inverse() is operator.mul 507 True 508 """ 509 return self._pointwise_inverse -
new file sage/categories/monoid_algebras.py
diff --git a/sage/categories/monoid_algebras.py b/sage/categories/monoid_algebras.py new file mode 100644
- + 1 r""" 2 MonoidAlgebras 3 """ 4 #***************************************************************************** 5 # Copyright (C) 2008 David Kohel <kohel@maths.usyd.edu> and 6 # William Stein <wstein@math.ucsd.edu> 7 # Nicolas M. Thiery <nthiery at users.sf.net> 8 # 9 # Distributed under the terms of the GNU General Public License (GPL) 10 # 11 # This code is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
