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

""" 

Module Functors 

 

AUTHORS: 

 

- Travis Scrimshaw (2017-10): Initial implementation of 

:class:`QuotientModuleFunctor` 

""" 

 

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

# Copyright (C) 2017 Travis Scrimshaw <tcscrims at gmail.com> 

# 

# This program is free software: you can redistribute it and/or modify 

# it under the terms of the GNU General Public License as published by 

# the Free Software Foundation, either version 2 of the License, or 

# (at your option) any later version. 

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

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

 

############################################################## 

# Construction functor for quotient modules 

############################################################## 

 

from sage.categories.pushout import ConstructionFunctor 

from sage.categories.modules import Modules 

 

class QuotientModuleFunctor(ConstructionFunctor): 

r""" 

Construct the quotient of a module by a submodule. 

 

INPUT: 

 

- ``relations`` -- a module 

 

.. NOTE:: 

 

This construction functor keeps track of the basis of defining 

``relations``. It can only be applied to free modules into which 

this basis coerces. 

 

EXAMPLES:: 

 

sage: A = (1/2)*ZZ^2 

sage: B = 2*ZZ^2 

sage: Q = A / B 

sage: F = Q.construction()[0] 

sage: F 

QuotientModuleFunctor 

sage: F(A) == Q 

True 

 

The modules are constructed from the cover not the ambient module:: 

 

sage: F(B.ambient_module()) == Q 

False 

 

We can construct quotients from different modules:: 

 

sage: F((1/2)*ZZ^2) 

Finitely generated module V/W over Integer Ring with invariants (4, 4) 

sage: F(ZZ^2) 

Finitely generated module V/W over Integer Ring with invariants (2, 2) 

sage: F(2*ZZ^2) 

Finitely generated module V/W over Integer Ring with invariants () 

 

This functor is used for constructing pushouts:: 

 

sage: A = ZZ^3 

sage: x,y,z = A.basis() 

sage: A1 = A.submodule([x]) 

sage: A2 = A.submodule([y, 2*x]) 

sage: B1 = A.submodule([]) 

sage: B2 = A.submodule([2*x]) 

sage: Q1 = A1 / B1 

sage: Q2 = A2 / B2 

sage: q3 = Q1.an_element() + Q2.an_element() 

""" 

rank = 5 # ranking of functor, not rank of module 

 

def __init__(self, relations): 

""" 

Initialization of ``self``. 

 

TESTS:: 

 

sage: from sage.modules.module_functors import QuotientModuleFunctor 

sage: B = (2/3)*ZZ^2 

sage: F = QuotientModuleFunctor(B) 

sage: TestSuite(F).run() 

""" 

R = relations.category().base_ring() 

ConstructionFunctor.__init__(self, Modules(R), Modules(R)) 

self._relations = relations 

 

def relations(self): 

""" 

Return the defining relations of ``self``. 

 

EXAMPLES:: 

 

sage: A = (ZZ**2) / span([[4,0],[0,3]], ZZ) 

sage: A.construction()[0].relations() 

Free module of degree 2 and rank 2 over Integer Ring 

Echelon basis matrix: 

[4 0] 

[0 3] 

""" 

return self._relations 

 

def _apply_functor(self, ambient): 

""" 

Apply the functor to an object of ``self``'s domain. 

 

TESTS:: 

 

sage: A = ZZ^3 

sage: B = 2 * A 

sage: C = 4 * A 

sage: D = B / C 

sage: F = D.construction()[0] 

sage: D == F(D.construction()[1]) 

True 

""" 

return ambient.quotient(self._relations) 

 

def __eq__(self, other): 

""" 

The quotient functor ``self`` is equal to ``other`` if 

it is a :class:`QuotientModuleFunctor` and the relations 

subspace are equal. 

 

EXAMPLES:: 

 

sage: F1 = ((ZZ^3) / (4*ZZ^3)).construction()[0] 

sage: F2 = ((2*ZZ^3) / (4*ZZ^3)).construction()[0] 

sage: F1 == F2 

True 

sage: F3 = ((ZZ^3) / (8*ZZ^3)).construction()[0] 

sage: F1 == F3 

False 

""" 

if not isinstance(other, QuotientModuleFunctor): 

return False 

return self._relations == other._relations 

 

def __ne__(self, other): 

r""" 

Check whether ``self`` is not equal to ``other``. 

 

EXAMPLES:: 

 

sage: F1 = ((ZZ^3) / (4*ZZ^3)).construction()[0] 

sage: F2 = ((2*ZZ^3) / (4*ZZ^3)).construction()[0] 

sage: F1 != F2 

False 

sage: F3 = ((ZZ^3) / (8*ZZ^3)).construction()[0] 

sage: F1 != F3 

True 

""" 

return not (self == other) 

 

def merge(self, other): 

r""" 

Merge the construction functors ``self`` and ``other``. 

 

EXAMPLES:: 

 

sage: A = ZZ^3 

sage: x,y,z = A.basis() 

sage: A1 = A.submodule([x]) 

sage: A2 = A.submodule([y, 2*x]) 

sage: B1 = A.submodule([]) 

sage: B2 = A.submodule([2*x]) 

sage: Q1 = A1 / B1 

sage: Q2 = A2 / B2 

sage: F1 = Q1.construction()[0] 

sage: F2 = Q2.construction()[0] 

sage: F3 = F1.merge(F2) 

sage: q3 = Q1.an_element() + Q2.an_element() 

sage: q3.parent() == F3(A1 + A2) 

True 

 

sage: G = A1.construction()[0]; G 

SubspaceFunctor 

sage: F1.merge(G) 

sage: F2.merge(G) 

""" 

if isinstance(other, QuotientModuleFunctor): 

return QuotientModuleFunctor(self._relations + other._relations)