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

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

r""" 

Dynamical systems for products of projective spaces 

 

This class builds on the prouct projective space class. 

The main constructor functions are given by ``DynamicalSystem`` and 

``DynamicalSystem_projective``. The constructors function can take either 

polynomials or a morphism from which to construct a dynamical system. 

 

The must be specified. 

 

EXAMPLES:: 

 

sage: P1xP1.<x,y,u,v> = ProductProjectiveSpaces(QQ, [1, 1]) 

sage: DynamicalSystem_projective([x^2*u, y^2*v, x*v^2, y*u^2], domain=P1xP1) 

Dynamical System of Product of projective spaces P^1 x P^1 over Rational Field 

Defn: Defined by sending (x : y , u : v) to 

(x^2*u : y^2*v , x*v^2 : y*u^2). 

""" 

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

# Copyright (C) 2014 Ben Hutz <bn4941@gmail.com> 

# 

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

# 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 copy import copy 

from sage.dynamics.arithmetic_dynamics.generic_ds import DynamicalSystem 

from sage.dynamics.arithmetic_dynamics.projective_ds import DynamicalSystem_projective 

from sage.rings.all import ZZ 

from sage.rings.quotient_ring import QuotientRing_generic 

from sage.schemes.product_projective.morphism import ProductProjectiveSpaces_morphism_ring 

 

 

class DynamicalSystem_product_projective(DynamicalSystem, 

ProductProjectiveSpaces_morphism_ring): 

r""" 

The class of dynamical systems on products of projective spaces. 

 

.. WARNING:: 

 

You should not create objects of this class directly because 

no type or consistency checking is performed. The preferred 

method to construct such dynamical systems is to use 

:func:`~sage.dynamics.arithmetic_dynamics.generic_ds.DynamicalSystem_projective` 

function. 

 

INPUT: 

 

- ``polys`` -- a list of ``n_1 + \cdots + n_r`` multi-homogeneous polynomials, all 

of which should have the same parent 

 

- ``domain`` -- a projective scheme embedded in 

``P^{n_1-1} \times \cdots \times P^{n_r-1}`` 

 

EXAMPLES:: 

 

sage: T.<x,y,z,w,u> = ProductProjectiveSpaces([2, 1], QQ) 

sage: DynamicalSystem_projective([x^2, y^2, z^2, w^2, u^2], domain=T) 

Dynamical System of Product of projective spaces P^2 x P^1 over Rational Field 

Defn: Defined by sending (x : y : z , w : u) to 

(x^2 : y^2 : z^2 , w^2 : u^2). 

""" 

 

def __init__(self, polys, domain): 

r""" 

The Python constructor. 

 

See :class:`DynamicalSystem` for details. 

 

EXAMPLES:: 

 

sage: T.<x,y,w,u> = ProductProjectiveSpaces([1, 1], QQ) 

sage: DynamicalSystem_projective([x^2, y^2, w^2, u^2], domain=T) 

Dynamical System of Product of projective spaces P^1 x P^1 over Rational Field 

Defn: Defined by sending (x : y , w : u) to 

(x^2 : y^2 , w^2 : u^2). 

""" 

DynamicalSystem.__init__(self, polys, domain) 

 

def _call_with_args(self, P, check=True): 

r""" 

Make dynamical systems of products of projective spaces callable. 

 

INPUT: 

 

- ``P`` -- a point in the domain 

 

- ``check`` -- Boolean - whether or not to perform the input checks 

on the image point (Default: ``True``) 

 

OUTPUT: The image point in the codomain 

 

EXAMPLES:: 

 

sage: T.<x,y,z,w,u> = ProductProjectiveSpaces([2, 1], QQ) 

sage: F = DynamicalSystem_projective([x^2*u, y^2*w, z^2*u, w^2, u^2], domain=T) 

sage: F(T([2, 1, 3, 0, 1])) 

(4/9 : 0 : 1 , 0 : 1) 

""" 

if check: 

from sage.schemes.product_projective.point import ProductProjectiveSpaces_point_ring 

if not isinstance(P, ProductProjectiveSpaces_point_ring): 

try: 

P = self.domain()(P) 

except (TypeError, NotImplementedError): 

raise TypeError("%s fails to convert into the map's domain %s, but a `pushforward` method is not properly implemented"%(P, self.domain())) 

elif self.domain()!= P.codomain(): 

raise TypeError("%s fails to convert into the map's domain %s, but a `pushforward` method is not properly implemented"%(P, self.domain())) 

 

A = self.domain() 

Q = list(P) 

newP = [f(Q) for f in self.defining_polynomials()] 

return(A.point(newP, check)) 

 

def nth_iterate(self, P, n, normalize=False): 

r""" 

Return the ``n``-th iterate of ``P`` by this dynamical system. 

 

If ``normalize`` is ``True``, then the coordinates are 

automatically normalized. 

 

.. TODO:: Is there a more efficient way to do this? 

 

INPUT: 

 

- ``P`` -- a point in ``self.domain()`` 

 

- ``n`` -- a positive integer 

 

- ``normalize`` -- (default: ``False``) boolean 

 

OUTPUT: A point in ``self.codomain()`` 

 

EXAMPLES:: 

 

sage: Z.<a,b,x,y,z> = ProductProjectiveSpaces([1, 2], QQ) 

sage: f = DynamicalSystem_projective([a^3, b^3 + a*b^2, x^2, y^2 - z^2, z*y], domain=Z) 

sage: P = Z([1, 1, 1, 1, 1]) 

sage: f.nth_iterate(P, 3) 

(1/1872 : 1 , 1 : 1 : 0) 

 

:: 

 

sage: Z.<a,b,x,y> = ProductProjectiveSpaces([1, 1], ZZ) 

sage: f = DynamicalSystem_projective([a*b, b^2, x^3 - y^3, y^2*x], domain=Z) 

sage: P = Z([2, 6, 2, 4]) 

sage: f.nth_iterate(P, 2, normalize = True) 

(1 : 3 , 407 : 112) 

""" 

if P.codomain() != self.domain(): 

raise TypeError("point is not defined over domain of function") 

n = ZZ(n) 

if n < 0: 

raise TypeError("must be a forward orbit") 

if n == 0: 

return(self) 

else: 

Q = self(P) 

if normalize == True: 

Q.normalize_coordinates() 

for i in range(2,n+1): 

Q = self(Q) 

if normalize == True: 

Q.normalize_coordinates() 

return(Q) 

 

def orbit(self, P, N, **kwds): 

r""" 

Return the orbit of `P` by this dynamical system. 

 

Let `F` be this dynamical system. If `N` is an integer return `[P,F(P),\ldots,F^N(P)]`. 

 

If `N` is a list or tuple `N = [m, k]` return `[F^m(P),\ldots,F^k(P)]`. 

Automatically normalize the points if ``normalize == True``. Perform the checks on point initialize if 

``check==True``. 

 

INPUT: 

 

- ``P`` -- a point in ``self.domain()`` 

 

- ``N`` -- a non-negative integer or list or tuple of two non-negative integers 

 

kwds: 

 

- ``check`` -- (default: ``True``) boolean 

 

- ``normalize`` -- (default: ``False``) boolean 

 

 

OUTPUT: a list of points in ``self.codomain()`` 

 

EXAMPLES:: 

 

sage: Z.<a,b,x,y,z> = ProductProjectiveSpaces([1, 2], QQ) 

sage: f = DynamicalSystem_projective([a^3, b^3 + a*b^2, x^2, y^2 - z^2, z*y], domain=Z) 

sage: P = Z([1, 1, 1, 1, 1]) 

sage: f.orbit(P, 3) 

[(1 : 1 , 1 : 1 : 1), (1/2 : 1 , 1 : 0 : 1), (1/12 : 1 , -1 : 1 : 0), (1/1872 : 1 , 1 : 1 : 0)] 

 

:: 

 

sage: Z.<a,b,x,y> = ProductProjectiveSpaces([1, 1], ZZ) 

sage: f = DynamicalSystem_projective([a*b, b^2, x^3 - y^3, y^2*x], domain=Z) 

sage: P = Z([2, 6, 2, 4]) 

sage: f.orbit(P, 3, normalize=True) 

[(1 : 3 , 1 : 2), (1 : 3 , -7 : 4), (1 : 3 , 407 : 112), (1 : 3 , 66014215 : 5105408)] 

""" 

if P.codomain() != self.domain(): 

raise TypeError("point is not defined over domain of function") 

if not isinstance(N, (list,tuple)): 

N = [0, N] 

try: 

N[0] = ZZ(N[0]) 

N[1] = ZZ(N[1]) 

except TypeError: 

raise TypeError("orbit bounds must be integers") 

if N[0] < 0 or N[1] < 0: 

raise TypeError("orbit bounds must be non-negative") 

if N[0] > N[1]: 

return([]) 

 

Q = copy(P) 

check = kwds.pop("check", True) 

normalize = kwds.pop("normalize", False) 

 

if normalize == True: 

Q.normalize_coordinates() 

for i in range(1, N[0]+1): 

Q = self(Q, check) 

if normalize == True: 

Q.normalize_coordinates() 

orb = [Q] 

for i in range(N[0]+1, N[1]+1): 

Q = self(Q, check) 

if normalize == True: 

Q.normalize_coordinates() 

orb.append(Q) 

return(orb) 

 

def nth_iterate_map(self, n): 

r""" 

Return the nth iterate of this dynamical system. 

 

ALGORITHM: 

 

Uses a form of successive squaring to reduce computations. 

 

 

.. TODO:: This could be improved. 

 

INPUT: 

 

- ``n`` -- a positive integer 

 

OUTPUT: A dynamical system of products of projective spaces 

 

EXAMPLES:: 

 

sage: Z.<a,b,x,y,z> = ProductProjectiveSpaces([1 , 2], QQ) 

sage: f = DynamicalSystem_projective([a^3, b^3, x^2, y^2, z^2], domain=Z) 

sage: f.nth_iterate_map(3) 

Dynamical System of Product of projective spaces P^1 x P^2 over 

Rational Field 

Defn: Defined by sending (a : b , x : y : z) to 

(a^27 : b^27 , x^8 : y^8 : z^8). 

""" 

E = self.domain() 

D = int(n) 

if D < 0: 

raise TypeError("iterate number must be a nonnegative integer") 

N = sum([E.ambient_space()[i].dimension_relative() + 1 for i in range(E.ambient_space().num_components())]) 

F = list(self._polys) 

Coord_ring = E.coordinate_ring() 

if isinstance(Coord_ring, QuotientRing_generic): 

PHI = [gen.lift() for gen in Coord_ring.gens()] 

else: 

PHI = list(Coord_ring.gens()) 

 

while D: 

if D&1: 

PHI = [poly(*F) for poly in PHI] 

if D > 1: #avoid extra iterate 

F = [poly(*F) for poly in F] #'square' 

D >>= 1 

return DynamicalSystem_projective(PHI, domain=self.domain())