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

""" 

Homomorphisms of abelian groups 

 

.. TODO:: 

 

- there must be a homspace first 

 

- there should be hom and Hom methods in abelian group 

 

AUTHORS: 

 

- David Joyner (2006-03-03): initial version 

""" 

 

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

# Copyright (C) 2006 David Joyner and William Stein <wstein@gmail.com> 

# 

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

# 

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

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

from __future__ import print_function 

 

from sage.groups.perm_gps.permgroup import * 

from sage.interfaces.gap import * 

from sage.categories.morphism import * 

from sage.categories.homset import * 

 

from sage.misc.all import prod 

 

 

def is_AbelianGroupMorphism(f): 

return isinstance(f, AbelianGroupMorphism) 

 

 

class AbelianGroupMap(Morphism): 

""" 

A set-theoretic map between AbelianGroups. 

""" 

def __init__(self, parent): 

""" 

The Python constructor. 

""" 

Morphism.__init__(self, parent) 

 

def _repr_type(self): 

return "AbelianGroup" 

 

 

class AbelianGroupMorphism_id(AbelianGroupMap): 

""" 

Return the identity homomorphism from X to itself. 

 

EXAMPLES: 

""" 

def __init__(self, X): 

AbelianGroupMorphism.__init__(self, X.Hom(X)) 

 

def _repr_defn(self): 

return "Identity map of " + str(X) 

 

 

class AbelianGroupMorphism(Morphism): 

""" 

Some python code for wrapping GAP's GroupHomomorphismByImages 

function for abelian groups. Returns "fail" if gens does not 

generate self or if the map does not extend to a group 

homomorphism, self - other. 

 

EXAMPLES:: 

 

sage: G = AbelianGroup(3,[2,3,4],names="abc"); G 

Multiplicative Abelian group isomorphic to C2 x C3 x C4 

sage: a,b,c = G.gens() 

sage: H = AbelianGroup(2,[2,3],names="xy"); H 

Multiplicative Abelian group isomorphic to C2 x C3 

sage: x,y = H.gens() 

 

sage: from sage.groups.abelian_gps.abelian_group_morphism import AbelianGroupMorphism 

sage: phi = AbelianGroupMorphism(H,G,[x,y],[a,b]) 

 

TESTS:: 

 

sage: G.<x,y> = AbelianGroup(2,[2,3]) 

sage: H.<a,b,c> = AbelianGroup(3,[2,3,4]) 

sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,b]) 

sage: Hom(G,H) == phi.parent() 

True 

 

AUTHORS: 

 

- David Joyner (2006-02) 

""" 

 

# There is a homomorphism from H to G but not from G to H: 

# 

# sage: phi = AbelianGroupMorphism_im_gens(G,H,[a*b,a*c],[x,y]) 

#------------------------------------------------------------ 

#Traceback (most recent call last): 

# File "<ipython console>", line 1, in ? 

# File ".abeliangp_hom.sage.py", line 737, in __init__ 

# raise TypeError, "Sorry, the orders of the corresponding elements in %s, %s must be equal."%(genss,imgss) 

#TypeError: Sorry, the orders of the corresponding elements in [a*b, a*c], [x, y] must be equal. 

# 

# sage: phi = AbelianGroupMorphism_im_gens(G,H,[a*b,(a*c)^2],[x*y,y]) 

#------------------------------------------------------------ 

#Traceback (most recent call last): 

# File "<ipython console>", line 1, in ? 

# File ".abeliangp_hom.sage.py", line 730, in __init__ 

# raise TypeError, "Sorry, the list %s must generate G."%genss 

#TypeError: Sorry, the list [a*b, c^2] must generate G. 

 

def __init__(self, G, H, genss, imgss): 

from sage.categories.homset import Hom 

Morphism.__init__(self, Hom(G, H)) 

if len(genss) != len(imgss): 

raise TypeError("Sorry, the lengths of %s, %s must be equal." % (genss, imgss)) 

self._domain = G 

self._codomain = H 

if not(G.is_abelian()): 

raise TypeError("Sorry, the groups must be abelian groups.") 

if not(H.is_abelian()): 

raise TypeError("Sorry, the groups must be abelian groups.") 

G_domain = G.subgroup(genss) 

if G_domain.order() != G.order(): 

raise TypeError("Sorry, the list %s must generate G." % genss) 

# self.domain_invs = G.gens_orders() 

# self.codomaininvs = H.gens_orders() 

self.domaingens = genss 

self.codomaingens = imgss 

for i in range(len(self.domaingens)): 

if (self.domaingens[i]).order() != (self.codomaingens[i]).order(): 

raise TypeError("Sorry, the orders of the corresponding elements in %s, %s must be equal." % (genss, imgss)) 

 

def _gap_init_(self): 

""" 

Only works for finite groups. 

 

EXAMPLES:: 

 

sage: G = AbelianGroup(3,[2,3,4],names="abc"); G 

Multiplicative Abelian group isomorphic to C2 x C3 x C4 

sage: a,b,c = G.gens() 

sage: H = AbelianGroup(2,[2,3],names="xy"); H 

Multiplicative Abelian group isomorphic to C2 x C3 

sage: x,y = H.gens() 

sage: phi = AbelianGroupMorphism(H,G,[x,y],[a,b]) 

sage: phi._gap_init_() 

'phi := GroupHomomorphismByImages(G,H,[x, y],[a, b])' 

""" 

G = (self.domain())._gap_init_() 

H = (self.codomain())._gap_init_() 

s3 = 'G:=%s; H:=%s' % (G, H) 

gap.eval(s3) 

gensG = self.domain().variable_names() # the Sage group generators 

gensH = self.codomain().variable_names() 

s1 = "gensG := GeneratorsOfGroup(G)" # the GAP group generators 

gap.eval(s1) 

s2 = "gensH := GeneratorsOfGroup(H)" 

gap.eval(s2) 

for i in range(len(gensG)): # making the Sage group gens 

cmd = ("%s := gensG["+str(i+1)+"]") % gensG[i] # correspond to the Sage group gens 

gap.eval(cmd) 

for i in range(len(gensH)): 

cmd = ("%s := gensH[" + str(i + 1) + "]") % gensH[i] 

gap.eval(cmd) 

args = str(self.domaingens) + "," + str(self.codomaingens) 

gap.eval("phi := GroupHomomorphismByImages(G,H," + args + ")") 

self.gap_hom_string = "phi := GroupHomomorphismByImages(G,H,"+args+")" 

return self.gap_hom_string 

 

def _repr_type(self): 

return "AbelianGroup" 

 

def kernel(self): 

""" 

Only works for finite groups. 

 

.. TODO:: 

 

not done yet; returns a gap object but should return a Sage group. 

 

EXAMPLES:: 

 

sage: H = AbelianGroup(3,[2,3,4],names="abc"); H 

Multiplicative Abelian group isomorphic to C2 x C3 x C4 

sage: a,b,c = H.gens() 

sage: G = AbelianGroup(2,[2,3],names="xy"); G 

Multiplicative Abelian group isomorphic to C2 x C3 

sage: x,y = G.gens() 

sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,b]) 

sage: phi.kernel() 

'Group([ ])' 

 

sage: H = AbelianGroup(3,[2,2,2],names="abc") 

sage: a,b,c = H.gens() 

sage: G = AbelianGroup(2,[2,2],names="x") 

sage: x,y = G.gens() 

sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,a]) 

sage: phi.kernel() 

'Group([ f1*f2 ])' 

""" 

cmd = self._gap_init_() 

gap.eval(cmd) 

return gap.eval("Kernel(phi)") 

 

def image(self, S): 

""" 

Return the image of the subgroup ``S`` by the morphism. 

 

This only works for finite groups. 

 

INPUT: 

 

- ``S`` -- a subgroup of the domain group ``G`` 

 

EXAMPLES:: 

 

sage: G = AbelianGroup(2,[2,3],names="xy") 

sage: x,y = G.gens() 

sage: subG = G.subgroup([x]) 

sage: H = AbelianGroup(3,[2,3,4],names="abc") 

sage: a,b,c = H.gens() 

sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,b]) 

sage: phi.image(subG) 

Multiplicative Abelian subgroup isomorphic to C2 generated by {a} 

""" 

return self.codomain().subgroup([self(g) for g in S.gens()]) 

 

def _call_(self, g): 

""" 

Some python code for wrapping GAP's Images function but only for 

permutation groups. Returns an error if g is not in G. 

 

EXAMPLES:: 

 

sage: H = AbelianGroup(3, [2,3,4], names="abc") 

sage: a,b,c = H.gens() 

sage: G = AbelianGroup(2, [2,3], names="xy") 

sage: x,y = G.gens() 

sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,b]) 

sage: phi(y*x) 

a*b 

sage: phi(y^2) 

b^2 

""" 

# g.word_problem is faster in general than word_problem(g) 

gens = self.codomaingens 

return prod(gens[(self.domaingens).index(wi[0])]**wi[1] 

for wi in g.word_problem(self.domaingens))