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

r""" 

Constructor for skew polynomial rings 

 

This module provides the function :func:`SkewPolynomialRing`, which constructs 

rings of univariate skew polynomials, and implements caching to prevent the 

same ring being created in memory multiple times (which is wasteful and breaks 

the general assumption in Sage that parents are unique). 

 

AUTHOR: 

 

- Xavier Caruso (2012-06-29): initial version 

 

- Arpit Merchant (2016-08-04): improved docstrings, added doctests and refactored method 

 

- Johan Rosenkilde (2016-08-03): changes to import format 

 

""" 

 

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

# Copyright (C) 2012 Xavier Caruso <xavier.caruso@normalesup.org> 

# 

# 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/ 

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

 

from __future__ import print_function, absolute_import, division 

from sage import categories 

import cysignals 

import sage.rings.ring as ring 

from sage.structure.category_object import normalize_names 

from sage.rings.finite_rings.finite_field_base import is_FiniteField 

from sage.categories.morphism import Morphism, IdentityMorphism 

 

def SkewPolynomialRing(base_ring, base_ring_automorphism=None, names=None, sparse=False): 

r""" 

Return the globally unique skew polynomial ring with the given properties 

and variable names. 

 

Given a ring `R` and a ring automorphism `\sigma` of `R`, the ring of 

skew polynomials `R[X, \sigma]` is the usual abelian group polynomial 

`R[X]` equipped with the modification multiplication deduced from the 

rule `X a = \sigma(a) X`. 

 

.. SEEALSO:: 

 

- :class:`sage.rings.polynomial.skew_polynomial_ring.SkewPolynomialRing_general` 

- :class:`sage.rings.polynomial.skew_polynomial_element.SkewPolynomial` 

 

INPUT: 

 

- ``base_ring`` -- a commutative ring 

 

- ``base_ring_automorphism`` -- an automorphism of the base ring 

(also called twisting map) 

 

- ``names`` -- a string or a list of strings 

 

- ``sparse`` -- a boolean (default: ``False``). Currently not supported. 

 

.. NOTE:: 

 

The current implementation of skew polynomial rings does not 

support derivations. Sparse skew polynomials and multivariate skew 

polynomials are also not implemented. 

 

OUTPUT: 

 

A univariate skew polynomial ring over ``base_ring`` twisted by 

``base_ring_automorphism`` when ``names`` is a string with no 

commas (``,``) or a list of length 1. Otherwise we raise a 

``NotImplementedError`` as multivariate skew polynomial rings are 

not yet implemented. 

 

UNIQUENESS and IMMUTABILITY: 

 

In Sage, there is exactly one skew polynomial ring for each 

triple (base ring, twisting map, name of the variable). 

 

EXAMPLES of VARIABLE NAME CONTEXT:: 

 

sage: R.<t> = ZZ[] 

sage: sigma = R.hom([t+1]) 

sage: S.<x> = SkewPolynomialRing(R, sigma); S 

Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring 

twisted by t |--> t + 1 

 

The names of the variables defined above cannot be arbitrarily 

modified because each skew polynomial ring is unique in Sage and other 

objects in Sage could have pointers to that skew polynomial ring. 

 

However, the variable can be changed within the scope of a ``with`` 

block using the localvars context:: 

 

sage: with localvars(S, ['y']): 

....: print(S) 

Skew Polynomial Ring in y over Univariate Polynomial Ring in t over Integer Ring 

twisted by t |--> t + 1 

 

SQUARE BRACKETS NOTATION: 

 

You can alternatively create a skew polynomial ring over `R` 

twisted by ``base_ring_automorphism`` by writing 

``R['varname', base_ring_automorphism]``. 

 

EXAMPLES: 

 

We first define the base ring:: 

 

sage: R.<t> = ZZ[]; R 

Univariate Polynomial Ring in t over Integer Ring 

 

and the twisting map:: 

 

sage: base_ring_automorphism = R.hom([t+1]); base_ring_automorphism 

Ring endomorphism of Univariate Polynomial Ring in t over Integer Ring 

Defn: t |--> t + 1 

 

Now, we are ready to define the skew polynomial ring:: 

 

sage: S = SkewPolynomialRing(R, base_ring_automorphism, names='x'); S 

Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring 

twisted by t |--> t + 1 

 

Use the diamond brackets notation to make the variable ready 

for use after you define the ring:: 

 

sage: S.<x> = SkewPolynomialRing(R, base_ring_automorphism) 

sage: (x + t)^2 

x^2 + (2*t + 1)*x + t^2 

 

Here is an example with the square bracket notations:: 

 

sage: S.<x> = R['x', base_ring_automorphism]; S 

Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring 

twisted by t |--> t + 1 

 

Rings with different variables names are different:: 

 

sage: R['x', base_ring_automorphism] == R['y', base_ring_automorphism] 

False 

 

TESTS: 

 

You must specify a variable name:: 

 

sage: SkewPolynomialRing(R, base_ring_automorphism) 

Traceback (most recent call last): 

... 

TypeError: you must specify the name of the variable 

 

With this syntax, it is not possible to omit the name of the 

variable neither in LHS nor in RHS. If we omit it in LHS, the 

variable is not created:: 

 

sage: Sy = R['y', base_ring_automorphism]; Sy 

Skew Polynomial Ring in y over Univariate Polynomial Ring in t over Integer Ring 

twisted by t |--> t + 1 

sage: y.parent() 

Traceback (most recent call last): 

... 

NameError: name 'y' is not defined 

 

If we omit it in RHS, sage tries to create a polynomial ring and fails:: 

 

sage: Sz.<z> = R[base_ring_automorphism] 

Traceback (most recent call last): 

... 

ValueError: variable name 'Ring endomorphism of Univariate Polynomial Ring in t over Integer Ring\n Defn: t |--> t + 1' is not alphanumeric 

 

Multivariate skew polynomial rings are not supported:: 

 

sage: S = SkewPolynomialRing(R, base_ring_automorphism,names=['x','y']) 

Traceback (most recent call last): 

... 

NotImplementedError: multivariate skew polynomials rings not supported 

 

Sparse skew polynomial rings are not implemented:: 

 

sage: S = SkewPolynomialRing(R, base_ring_automorphism, names='x', sparse=True) 

Traceback (most recent call last): 

... 

NotImplementedError: sparse skew polynomial rings are not implemented 

 

.. TODO:: 

 

- Sparse Skew Polynomial Ring 

- Multivariate Skew Polynomial Ring 

- Add derivations. 

""" 

if base_ring not in categories.rings.Rings().Commutative(): 

raise TypeError("base_ring must be a commutative ring") 

if base_ring_automorphism is None: 

base_ring_automorphism = IdentityMorphism(base_ring) 

else: 

if (not isinstance(base_ring_automorphism,Morphism) 

or base_ring_automorphism.domain() != base_ring 

or base_ring_automorphism.codomain() != base_ring): 

raise TypeError("base_ring_automorphism must be a ring automorphism of base_ring (=%s)" % base_ring) 

if sparse: 

raise NotImplementedError("sparse skew polynomial rings are not implemented") 

if names is None: 

raise TypeError("you must specify the name of the variable") 

try: 

names = normalize_names(1, names)[0] 

except IndexError: 

raise NotImplementedError("multivariate skew polynomials rings not supported") 

 

from sage.rings.polynomial.skew_polynomial_ring import SkewPolynomialRing_general 

return SkewPolynomialRing_general(base_ring, base_ring_automorphism, names, sparse)