Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

r""" 

Non-unital non-associative algebras 

""" 

#***************************************************************************** 

# Copyright (C) 2011 Nicolas M. Thiery <nthiery at users.sf.net> 

# 

# Distributed under the terms of the GNU General Public License (GPL) 

# http://www.gnu.org/licenses/ 

#****************************************************************************** 

 

from sage.misc.abstract_method import abstract_method 

from sage.misc.cachefunc import cached_method 

from sage.misc.lazy_attribute import lazy_attribute 

from sage.misc.lazy_import import LazyImport 

from sage.categories.category import Category 

from sage.categories.category_types import Category_over_base_ring 

from sage.categories.category_with_axiom import CategoryWithAxiom_over_base_ring 

from sage.categories.magmas import Magmas 

from sage.categories.additive_magmas import AdditiveMagmas 

from sage.categories.modules import Modules 

 

import six 

 

 

class MagmaticAlgebras(Category_over_base_ring): 

""" 

The category of algebras over a given base ring. 

 

An algebra over a ring `R` is a module over `R` endowed with a 

bilinear multiplication. 

 

.. WARNING:: 

 

:class:`MagmaticAlgebras` will eventually replace the current 

:class:`Algebras` for consistency with 

e.g. :wikipedia:`Algebras` which assumes neither associativity 

nor the existence of a unit (see :trac:`15043`). 

 

EXAMPLES:: 

 

sage: from sage.categories.magmatic_algebras import MagmaticAlgebras 

sage: C = MagmaticAlgebras(ZZ); C 

Category of magmatic algebras over Integer Ring 

sage: C.super_categories() 

[Category of additive commutative additive associative additive unital distributive magmas and additive magmas, 

Category of modules over Integer Ring] 

 

TESTS:: 

 

sage: TestSuite(C).run() 

""" 

 

@cached_method 

def super_categories(self): 

""" 

EXAMPLES:: 

 

sage: from sage.categories.magmatic_algebras import MagmaticAlgebras 

sage: MagmaticAlgebras(ZZ).super_categories() 

[Category of additive commutative additive associative additive unital distributive magmas and additive magmas, Category of modules over Integer Ring] 

 

sage: from sage.categories.additive_semigroups import AdditiveSemigroups 

sage: MagmaticAlgebras(ZZ).is_subcategory((AdditiveSemigroups() & Magmas()).Distributive()) 

True 

 

""" 

R = self.base_ring() 

# Note: The specifications impose `self` to be a subcategory 

# of the join of its super categories. Here the join is non 

# trivial, since some of the axioms of Modules (like the 

# commutativity of '+') are added to the left hand side. We 

# might want the infrastructure to take this join for us. 

return Category.join([(Magmas() & AdditiveMagmas()).Distributive(), Modules(R)], as_list=True) 

 

def additional_structure(self): 

r""" 

Return ``None``. 

 

Indeed, the category of (magmatic) algebras defines no new 

structure: a morphism of modules and of magmas between two 

(magmatic) algebras is a (magmatic) algebra morphism. 

 

.. SEEALSO:: :meth:`Category.additional_structure` 

 

.. TODO:: 

 

This category should be a 

:class:`~sage.categories.category_with_axiom.CategoryWithAxiom`, 

the axiom specifying the compatibility between the magma and 

module structure. 

 

EXAMPLES:: 

 

sage: from sage.categories.magmatic_algebras import MagmaticAlgebras 

sage: MagmaticAlgebras(ZZ).additional_structure() 

""" 

return None 

 

Associative = LazyImport('sage.categories.associative_algebras', 'AssociativeAlgebras', at_startup=True) 

Unital = LazyImport('sage.categories.unital_algebras', 'UnitalAlgebras', at_startup=True) 

 

class ParentMethods: 

 

@abstract_method(optional=True) 

def algebra_generators(self): 

""" 

Return a family of generators of this algebra. 

 

EXAMPLES:: 

 

sage: F = AlgebrasWithBasis(QQ).example(); F 

An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field 

sage: F.algebra_generators() 

Family (B[word: a], B[word: b], B[word: c]) 

""" 

 

class WithBasis(CategoryWithAxiom_over_base_ring): 

 

class ParentMethods: 

 

def algebra_generators(self): 

r""" 

Return generators for this algebra. 

 

This default implementation returns the basis of this algebra. 

 

OUTPUT: a family 

 

.. SEEALSO:: 

 

- :meth:`~sage.categories.modules_with_basis.ModulesWithBasis.ParentMethods.basis` 

- :meth:`MagmaticAlgebras.ParentMethods.algebra_generators` 

 

EXAMPLES:: 

 

sage: D4 = DescentAlgebra(QQ, 4).B() 

sage: D4.algebra_generators() 

Lazy family (...)_{i in Compositions of 4} 

 

sage: R.<x> = ZZ[] 

sage: P = PartitionAlgebra(1, x, R) 

sage: P.algebra_generators() 

Lazy family (Term map from Partition diagrams of order 1 to 

Partition Algebra of rank 1 with parameter x over Univariate Polynomial Ring in x 

over Integer Ring(i))_{i in Partition diagrams of order 1}  

""" 

return self.basis() 

 

@abstract_method(optional = True) 

def product_on_basis(self, i, j): 

""" 

The product of the algebra on the basis (optional). 

 

INPUT: 

 

- ``i``, ``j`` -- the indices of two elements of the 

basis of ``self`` 

 

Return the product of the two corresponding basis elements 

indexed by ``i`` and ``j``. 

 

If implemented, :meth:`product` is defined from 

it by bilinearity. 

 

EXAMPLES:: 

 

sage: A = AlgebrasWithBasis(QQ).example() 

sage: Word = A.basis().keys() 

sage: A.product_on_basis(Word("abc"),Word("cba")) 

B[word: abccba] 

""" 

 

@lazy_attribute 

def product(self): 

""" 

The product of the algebra, as per 

:meth:`Magmas.ParentMethods.product() 

<sage.categories.magmas.Magmas.ParentMethods.product>` 

 

By default, this is implemented using one of the following 

methods, in the specified order: 

 

- :meth:`.product_on_basis` 

- :meth:`._multiply` or :meth:`._multiply_basis` 

- :meth:`.product_by_coercion` 

 

EXAMPLES:: 

 

sage: A = AlgebrasWithBasis(QQ).example() 

sage: a, b, c = A.algebra_generators() 

sage: A.product(a + 2*b, 3*c) 

3*B[word: ac] + 6*B[word: bc] 

""" 

if self.product_on_basis is not NotImplemented: 

return self._product_from_product_on_basis_multiply 

# return self._module_morphism(self._module_morphism(self.product_on_basis, position = 0, codomain=self), 

# position = 1) 

elif hasattr(self, "_multiply") or hasattr(self, "_multiply_basis"): 

return self._product_from_combinatorial_algebra_multiply 

elif hasattr(self, "product_by_coercion"): 

return self.product_by_coercion 

else: 

return NotImplemented 

 

# Provides a product using the product_on_basis by calling linear_combination only once 

def _product_from_product_on_basis_multiply( self, left, right ): 

r""" 

Computes the product of two elements by extending 

bilinearly the method :meth:`product_on_basis`. 

 

EXAMPLES:: 

 

sage: A = AlgebrasWithBasis(QQ).example(); A 

An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field 

sage: (a,b,c) = A.algebra_generators() 

sage: A._product_from_product_on_basis_multiply(a*b + 2*c, a - b) 

B[word: aba] - B[word: abb] + 2*B[word: ca] - 2*B[word: cb] 

 

""" 

return self.linear_combination( ( self.product_on_basis( mon_left, mon_right ), coeff_left * coeff_right ) 

for ( mon_left, coeff_left ) in six.iteritems(left.monomial_coefficients()) 

for ( mon_right, coeff_right ) in six.iteritems(right.monomial_coefficients()) )