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

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

""" 

Free Zinbiel Algebras 

 

AUTHORS: 

 

- Travis Scrimshaw (2015-09): initial version 

""" 

 

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

# Copyright (C) 2015 Travis Scrimshaw <tscrimsh at umn.edu> 

# 

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

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

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

 

from sage.misc.cachefunc import cached_method 

from sage.categories.magmatic_algebras import MagmaticAlgebras 

from sage.categories.rings import Rings 

from sage.combinat.free_module import CombinatorialFreeModule 

from sage.combinat.words.words import Words 

from sage.combinat.words.alphabet import Alphabet 

from sage.sets.family import Family 

 

class FreeZinbielAlgebra(CombinatorialFreeModule): 

r""" 

The free Zinbiel algebra on `n` generators. 

 

Let `R` be a ring. A *Zinbiel algebra* is a non-associative 

algebra with multiplication `\circ` that satisfies 

 

.. MATH:: 

 

a \circ (b \circ c) = a \circ (b \circ c) + a \circ (c \circ b). 

 

Zinbiel algebras were first introduced by Loday (see [Lod1995]_ and 

[LV2012]_) as the Koszul dual to Leibniz algebras (hence the name 

coined by Lemaire). 

 

Zinbiel algebras are divided power algebras, in that for 

 

.. MATH:: 

 

x^{\circ n} = \bigl(x \circ (x \circ \cdots \circ( x \circ x) \cdots 

) \bigr) 

 

we have 

 

.. MATH:: 

 

x^{\circ m} \circ x^{\circ n} = \binom{n+m-1}{m} x^{n+m} 

 

and 

 

.. MATH:: 

 

\underbrace{\bigl( ( x \circ \cdots \circ x \circ (x \circ x) \cdots 

) \bigr)}_{n+1 \text{ times}} = n! x^n. 

 

.. NOTE:: 

 

This implies that Zinbiel algebras are not power associative. 

 

To every Zinbiel algebra, we can construct a corresponding commutative 

associative algebra by using the symmetrized product: 

 

.. MATH:: 

 

a * b = a \circ b + b \circ a. 

 

The free Zinbiel algebra on `n` generators is isomorphic as `R`-modules 

to the reduced tensor algebra `\bar{T}(R^n)` with the product 

 

.. MATH:: 

 

(x_0 x_1 \cdots x_p) \circ (x_{p+1} x_{p+2} \cdots x_{p+q}) 

= \sum_{\sigma \in S_{p,q}} x_0 (x_{\sigma(1)} x_{\sigma(2)} 

\cdots x_{\sigma(p+q)}, 

 

where `S_{p,q}` is the set of `(p,q)`-shuffles. 

 

The free Zinbiel algebra is free as a divided power algebra. Moreover, 

the corresponding commutative algebra is isomorphic to the (non-unital) 

shuffle algebra. 

 

INPUT: 

 

- ``R`` -- a ring 

- ``n`` -- (optional) the number of generators 

- ``names`` -- the generator names 

 

.. WARNING:: 

 

Currently the basis is indexed by all words over the variables, 

incuding the empty word. This is a slight abuse as it is suppose 

to be the indexed by all non-empty words. 

 

EXAMPLES: 

 

We create the free Zinbiel algebra and check the defining relation:: 

 

sage: Z.<x,y,z> = algebras.FreeZinbiel(QQ) 

sage: (x*y)*z 

Z[xyz] + Z[xzy] 

sage: x*(y*z) + x*(z*y) 

Z[xyz] + Z[xzy] 

 

We see that the Zinbiel algebra is not associative, nor even 

power associative:: 

 

sage: x*(y*z) 

Z[xyz] 

sage: x*(x*x) 

Z[xxx] 

sage: (x*x)*x 

2*Z[xxx] 

 

We verify that it is a divided powers algebra:: 

 

sage: (x*(x*x)) * (x*(x*(x*x))) 

15*Z[xxxxxxx] 

sage: binomial(3+4-1,4) 

15 

sage: (x*(x*(x*x))) * (x*(x*x)) 

20*Z[xxxxxxx] 

sage: binomial(3+4-1,3) 

20 

sage: ((x*x)*x)*x 

6*Z[xxxx] 

sage: (((x*x)*x)*x)*x 

24*Z[xxxxx] 

 

REFERENCES: 

 

- :wikipedia:`Zinbiel_algebra` 

 

- [Lod1995]_ 

 

- [LV2012]_ 

""" 

@staticmethod 

def __classcall_private__(cls, R, n=None, names=None): 

""" 

Standardize input to ensure a unique representation. 

 

TESTS:: 

 

sage: Z1.<x,y,z> = algebras.FreeZinbiel(QQ) 

sage: Z2.<x,y,z> = algebras.FreeZinbiel(QQ, 3) 

sage: Z3 = algebras.FreeZinbiel(QQ, 3, 'x,y,z') 

sage: Z4.<x,y,z> = algebras.FreeZinbiel(QQ, 'x,y,z') 

sage: Z1 is Z2 and Z1 is Z3 and Z1 is Z4 

True 

""" 

if isinstance(n, (list,tuple)): 

names = n 

n = len(names) 

elif isinstance(n, str): 

names = n.split(',') 

n = len(names) 

elif isinstance(names, str): 

names = names.split(',') 

elif n is None: 

n = len(names) 

return super(FreeZinbielAlgebra, cls).__classcall__(cls, R, n, tuple(names)) 

 

def __init__(self, R, n, names): 

""" 

Initialize ``self``. 

 

EXAMPLES:: 

 

sage: Z.<x,y,z> = algebras.FreeZinbiel(QQ) 

sage: TestSuite(Z).run() 

""" 

if R not in Rings: 

raise TypeError("argument R must be a ring") 

indices = Words(Alphabet(n, names=names)) 

cat = MagmaticAlgebras(R).WithBasis() 

self._n = n 

CombinatorialFreeModule.__init__(self, R, indices, prefix='Z', 

category=cat) 

self._assign_names(names) 

 

def _repr_term(self, t): 

""" 

Return a string representation of the basis element indexed by ``t``. 

 

EXAMPLES:: 

 

sage: Z.<x,y,z> = algebras.FreeZinbiel(QQ) 

sage: Z._repr_term(Z._indices('xyzxxy')) 

'Z[xyzxxy]' 

""" 

return "{!s}[{!s}]".format(self._print_options['prefix'], repr(t)[6:]) 

 

def _repr_(self): 

""" 

Return a string representation of ``self``. 

 

EXAMPLES:: 

 

sage: Z.<x,y,z> = algebras.FreeZinbiel(QQ) 

sage: Z 

Free Zinbiel algebra on generators (Z[x], Z[y], Z[z]) over Rational Field 

""" 

return "Free Zinbiel algebra on generators {} over {}".format( 

self.gens(), self.base_ring()) 

 

@cached_method 

def algebra_generators(self): 

""" 

Return the algebra generators of ``self``. 

 

EXAMPLES:: 

 

sage: Z.<x,y,z> = algebras.FreeZinbiel(QQ) 

sage: list(Z.algebra_generators()) 

[Z[x], Z[y], Z[z]] 

""" 

A = self.variable_names() 

return Family( A, lambda g: self.monomial(self._indices(g)) ) 

 

@cached_method 

def gens(self): 

""" 

Return the generators of ``self``. 

 

EXAMPLES:: 

 

sage: Z.<x,y,z> = algebras.FreeZinbiel(QQ) 

sage: Z.gens() 

(Z[x], Z[y], Z[z]) 

""" 

return tuple(self.algebra_generators()) 

 

def product_on_basis(self, x, y): 

""" 

Return the product of the basis elements indexed by ``x`` and ``y``. 

 

EXAMPLES:: 

 

sage: Z.<x,y,z> = algebras.FreeZinbiel(QQ) 

sage: (x*y)*z # indirect doctest 

Z[xyz] + Z[xzy] 

""" 

if not x: 

return self.monomial(y) 

x0 = self._indices(x[0]) 

return self.sum_of_monomials(x0 + sh for sh in x[1:].shuffle(y))