Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/toric/morphism.py
4079 views
1
r"""
2
Morphisms of Toric Varieties
3
4
There are three "obvious" ways to map toric varieties to toric
5
varieties:
6
7
1. Polynomial maps in local coordinates, the usual morphisms in
8
algebraic geometry.
9
10
2. Polynomial maps in the (global) homogeneous coordinates.
11
12
3. Toric morphisms, that is, algebraic morphisms equivariant with
13
respect to the torus action on the toric variety.
14
15
Both 2 and 3 are special cases of 1, which is just to say that we
16
always remain within the realm of algebraic geometry. But apart from
17
that, none is included in one of the other cases. In the examples
18
below, we will explore some algebraic maps that can or can not be
19
written as a toric morphism. Often a toric morphism can be written
20
with polynomial maps in homogeneous coordinates, but sometimes it
21
cannot.
22
23
The toric morphisms are perhaps the most mysterious at the
24
beginning. Let us quickly review their definition (See Definition
25
3.3.3 of [CLS]_). Let `\Sigma_1` be a fan in `N_{1,\RR}` and `\Sigma_2` be a
26
fan in `N_{2,\RR}`. A morphism `\phi: X_{\Sigma_1} \to X_{\Sigma_2}`
27
of the associated toric varieties is toric if `\phi` maps the maximal
28
torus `T_{N_1} \subseteq X_{\Sigma_1}` into `T_{N_2} \subseteq
29
X_{\Sigma_2}` and `\phi|_{T_N}` is a group homomorphism.
30
31
The data defining a toric morphism is precisely what defines a fan
32
morphism (see :mod:`~sage.geometry.fan_morphism`), extending the more
33
familiar dictionary between toric varieties and fans. Toric geometry
34
is a functor from the category of fans and fan morphisms to the
35
category of toric varieties and toric morphisms.
36
37
.. note::
38
39
Do not create the toric morphisms (or any morphism of schemes)
40
directly from the the ``SchemeMorphism...`` classes. Instead, use the
41
:meth:`~sage.schemes.generic.scheme.hom` method common to all
42
algebraic schemes to create new homomorphisms.
43
44
EXAMPLES:
45
46
First, consider the following embedding of `\mathbb{P}^1` into
47
`\mathbb{P}^2` ::
48
49
sage: P2.<x,y,z> = toric_varieties.P2()
50
sage: P1.<u,v> = toric_varieties.P1()
51
sage: P1.hom([0,u^2+v^2,u*v], P2)
52
Scheme morphism:
53
From: 1-d CPR-Fano toric variety covered by 2 affine patches
54
To: 2-d CPR-Fano toric variety covered by 3 affine patches
55
Defn: Defined on coordinates by sending [u : v] to
56
[0 : u^2 + v^2 : u*v]
57
58
This is a well-defined morphism of algebraic varieties because
59
homogeneously rescaled coordinates of a point of `\mathbb{P}^1` map to the same
60
point in `\mathbb{P}^2` up to its homogeneous rescalings. It is not
61
equivariant with respect to the torus actions
62
63
.. math::
64
65
\CC^\times \times \mathbb{P}^1,
66
(\mu,[u:v]) \mapsto [u:\mu v]
67
\quad\text{and}\quad
68
\left(\CC^\times\right)^2 \times \mathbb{P}^2,
69
((\alpha,\beta),[x:y:z]) \mapsto [x:\alpha y:\beta z]
70
,
71
72
hence it is not a toric morphism. Clearly, the problem is that
73
the map in homogeneous coordinates contains summands that transform
74
differently under the torus action. However, this is not the only
75
difficulty. For example, consider ::
76
77
sage: phi = P1.hom([0,u,v], P2); phi
78
Scheme morphism:
79
From: 1-d CPR-Fano toric variety covered by 2 affine patches
80
To: 2-d CPR-Fano toric variety covered by 3 affine patches
81
Defn: Defined on coordinates by sending [u : v] to
82
[0 : u : v]
83
84
This map is actually the embedding of the
85
:meth:`~sage.schemes.toric.variety.ToricVariety_field.orbit_closure`
86
associated to one of the rays of the fan of `\mathbb{P}^2`. Now the
87
morphism is equivariant with respect to **some** map `\CC^\times \to
88
(\CC^\times)^2` of the maximal tori of `\mathbb{P}^1` and
89
`\mathbb{P}^2`. But this map of the maximal tori cannot be the same as
90
``phi`` defined above. Indeed, the image of ``phi`` completely misses
91
the maximal torus `T_{\mathbb{P}^2} = \{ [x:y:z] | x\not=0, y\not=0,
92
z\not=0 \}` of `\mathbb{P}^2`.
93
94
Consider instead the following morphism of fans::
95
96
sage: fm = FanMorphism( matrix(ZZ,[[1,0]]), P1.fan(), P2.fan() ); fm
97
Fan morphism defined by the matrix
98
[1 0]
99
Domain fan: Rational polyhedral fan in 1-d lattice N
100
Codomain fan: Rational polyhedral fan in 2-d lattice N
101
102
which also defines a morphism of toric varieties::
103
104
sage: P1.hom(fm, P2)
105
Scheme morphism:
106
From: 1-d CPR-Fano toric variety covered by 2 affine patches
107
To: 2-d CPR-Fano toric variety covered by 3 affine patches
108
Defn: Defined by sending Rational polyhedral fan in 1-d lattice N
109
to Rational polyhedral fan in 2-d lattice N.
110
111
The fan morphism map is equivalent to the following polynomial map::
112
113
sage: _.as_polynomial_map()
114
Scheme morphism:
115
From: 1-d CPR-Fano toric variety covered by 2 affine patches
116
To: 2-d CPR-Fano toric variety covered by 3 affine patches
117
Defn: Defined on coordinates by sending [u : v] to
118
[u : v : v]
119
120
Finally, here is an example of a fan morphism that cannot be written
121
using homogeneous polynomials. Consider the blowup `O_{\mathbb{P}^1}(2)
122
\to \CC^2/\ZZ_2`. In terms of toric data, this blowup is::
123
124
sage: A2_Z2 = toric_varieties.A2_Z2()
125
sage: A2_Z2.fan().rays()
126
(N(1, 0), N(1, 2))
127
sage: O2_P1 = A2_Z2.resolve(new_rays=[(1,1)])
128
sage: blowup = O2_P1.hom(identity_matrix(2), A2_Z2)
129
sage: blowup.as_polynomial_map()
130
Traceback (most recent call last):
131
...
132
TypeError: The fan morphism cannot be written in homogeneous polynomials.
133
134
If we denote the homogeneous coordinates of `O_{\mathbb{P}^1}(2)` by
135
`x`, `t`, `y` corresponding to the rays `(1,2)`, `(1,1)`, and `(1,0)`
136
then the blow-up map is [BB]_:
137
138
.. math::
139
140
f: O_{\mathbb{P}^1}(2) \to \CC^2/\ZZ_2, \quad
141
(x,t,y) \mapsto \left( x\sqrt{t}, y\sqrt{t} \right)
142
143
which requires square roots.
144
145
REFERENCES:
146
147
.. [BB]
148
Gavin Brown, Jaroslaw Buczynski:
149
Maps of toric varieties in Cox coordinates,
150
http://arxiv.org/abs/1004.4924
151
"""
152
153
154
#*****************************************************************************
155
# Copyright (C) 2011 Volker Braun <[email protected]>
156
# Copyright (C) 2010 Andrey Novoseltsev <[email protected]>
157
# Copyright (C) 2006 William Stein <[email protected]>
158
# Distributed under the terms of the GNU General Public License (GPL)
159
# http://www.gnu.org/licenses/
160
#*****************************************************************************
161
162
from sage.structure.sequence import Sequence
163
from sage.rings.all import ZZ
164
165
from sage.schemes.generic.scheme import is_Scheme
166
from sage.schemes.generic.morphism import (
167
is_SchemeMorphism,
168
SchemeMorphism, SchemeMorphism_point, SchemeMorphism_polynomial
169
)
170
171
172
173
############################################################################
174
# A points on a toric variety determined by homogeneous coordinates.
175
class SchemeMorphism_point_toric_field(SchemeMorphism_point):
176
"""
177
A point of a toric variety determined by homogeneous coordinates
178
in a field.
179
180
.. WARNING::
181
182
You should not create objects of this class directly. Use the
183
:meth:`~sage.schemes.generic.scheme.hom` method of
184
:class:`toric varieties
185
<sage.schemes.toric.variety.ToricVariety_field>`
186
instead.
187
188
INPUT:
189
190
- ``X`` -- toric variety or subscheme of a toric variety.
191
192
- ``coordinates`` -- list of coordinates in the base field of ``X``.
193
194
- ``check`` -- if ``True`` (default), the input will be checked for
195
correctness.
196
197
OUTPUT:
198
199
A :class:`SchemeMorphism_point_toric_field`.
200
201
TESTS::
202
203
sage: fan = FaceFan(lattice_polytope.octahedron(2))
204
sage: P1xP1 = ToricVariety(fan)
205
sage: P1xP1(1,2,3,4)
206
[1 : 2 : 3 : 4]
207
"""
208
# Mimicking affine/projective classes
209
def __init__(self, X, coordinates, check=True):
210
r"""
211
See :class:`SchemeMorphism_point_toric_field` for documentation.
212
213
TESTS::
214
215
sage: fan = FaceFan(lattice_polytope.octahedron(2))
216
sage: P1xP1 = ToricVariety(fan)
217
sage: P1xP1(1,2,3,4)
218
[1 : 2 : 3 : 4]
219
"""
220
# Convert scheme to its set of points over the base ring
221
if is_Scheme(X):
222
X = X(X.base_ring())
223
super(SchemeMorphism_point_toric_field, self).__init__(X)
224
if check:
225
# Verify that there are the right number of coords
226
# Why is it not done in the parent?
227
if is_SchemeMorphism(coordinates):
228
coordinates = list(coordinates)
229
if not isinstance(coordinates, (list, tuple)):
230
raise TypeError("coordinates must be a scheme point, list, "
231
"or tuple. Got %s" % coordinates)
232
d = X.codomain().ambient_space().ngens()
233
if len(coordinates) != d:
234
raise ValueError("there must be %d coordinates! Got only %d: "
235
"%s" % (d, len(coordinates), coordinates))
236
# Make sure the coordinates all lie in the appropriate ring
237
coordinates = Sequence(coordinates, X.value_ring())
238
# Verify that the point satisfies the equations of X.
239
X.codomain()._check_satisfies_equations(coordinates)
240
self._coords = coordinates
241
242
243
244
############################################################################
245
# A morphism of toric varieties determined by homogeneous polynomials.
246
class SchemeMorphism_polynomial_toric_variety(SchemeMorphism_polynomial):
247
"""
248
A morphism determined by homogeneous polynomials.
249
250
.. WARNING::
251
252
You should not create objects of this class directly. Use the
253
:meth:`~sage.schemes.generic.scheme.hom` method of
254
:class:`toric varieties
255
<sage.schemes.toric.variety.ToricVariety_field>`
256
instead.
257
258
INPUT:
259
260
Same as for
261
:class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial`.
262
263
OUPUT:
264
265
A :class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety`.
266
267
TESTS::
268
269
sage: fan = FaceFan(lattice_polytope.octahedron(2))
270
sage: P1xP1 = ToricVariety(fan)
271
sage: P1xP1.inject_variables()
272
Defining z0, z1, z2, z3
273
sage: P1 = P1xP1.subscheme(z0-z2)
274
sage: H = P1xP1.Hom(P1)
275
sage: import sage.schemes.toric.morphism as MOR
276
sage: MOR.SchemeMorphism_polynomial_toric_variety(H, [z0,z1,z0,z3])
277
Scheme morphism:
278
From: 2-d toric variety covered by 4 affine patches
279
To: Closed subscheme of 2-d toric variety
280
covered by 4 affine patches defined by:
281
z0 - z2
282
Defn: Defined on coordinates by sending
283
[z0 : z1 : z2 : z3] to [z0 : z1 : z0 : z3]
284
"""
285
286
def __init__(self, parent, polynomials, check=True):
287
r"""
288
See :class:`SchemeMorphism_polynomial_toric_variety` for documentation.
289
290
TESTS::
291
292
sage: fan = FaceFan(lattice_polytope.octahedron(2))
293
sage: P1xP1 = ToricVariety(fan)
294
sage: P1xP1.inject_variables()
295
Defining z0, z1, z2, z3
296
sage: P1 = P1xP1.subscheme(z0-z2)
297
sage: H = P1xP1.Hom(P1)
298
sage: import sage.schemes.toric.morphism as MOR
299
sage: MOR.SchemeMorphism_polynomial_toric_variety(H, [z0,z1,z0,z3])
300
Scheme morphism:
301
From: 2-d toric variety covered by 4 affine patches
302
To: Closed subscheme of 2-d toric variety
303
covered by 4 affine patches defined by:
304
z0 - z2
305
Defn: Defined on coordinates by sending
306
[z0 : z1 : z2 : z3] to [z0 : z1 : z0 : z3]
307
"""
308
SchemeMorphism_polynomial.__init__(self, parent, polynomials, check)
309
if check:
310
# Check that defining polynomials are homogeneous (degrees can be
311
# different if the target uses weighted coordinates)
312
for p in self.defining_polynomials():
313
if not self.domain().ambient_space().is_homogeneous(p):
314
raise ValueError("%s is not homogeneous!" % p)
315
316
def as_fan_morphism(self):
317
"""
318
Express the morphism as a map defined by a fan morphism.
319
320
OUTPUT:
321
322
A :class:`SchemeMorphism_polynomial_toric_variety`. Raises a
323
``TypeError`` if the morphism cannot be written in such a way.
324
325
EXAMPLES::
326
327
sage: A1.<z> = toric_varieties.A1()
328
sage: P1 = toric_varieties.P1()
329
sage: patch = A1.hom([1,z], P1)
330
sage: patch.as_fan_morphism()
331
Traceback (most recent call last):
332
...
333
NotImplementedError: expressing toric morphisms as fan morphisms is
334
not implemented yet!
335
"""
336
raise NotImplementedError("expressing toric morphisms as fan "
337
"morphisms is not implemented yet!")
338
339
340
############################################################################
341
# A morphism of toric varieties determined by a fan morphism
342
class SchemeMorphism_fan_toric_variety(SchemeMorphism):
343
"""
344
Construct a morphism determined by a fan morphism
345
346
.. WARNING::
347
348
You should not create objects of this class directly. Use the
349
:meth:`~sage.schemes.generic.scheme.hom` method of
350
:class:`toric varieties
351
<sage.schemes.toric.variety.ToricVariety_field>`
352
instead.
353
354
INPUT:
355
356
- ``parent`` -- Hom-set whose domain and codomain are toric varieties.
357
358
- ``fan_morphism`` -- A morphism of fans whose domain and codomain
359
fans equal the fans of the domain and codomain in the ``parent``
360
Hom-set.
361
362
- ``check`` -- boolean (optional, default:``True``). Whether to
363
check the input for consistency.
364
365
OUPUT:
366
367
A :class:`~sage.schemes.generic.morphism.SchemeMorphism_fan_toric_variety`.
368
369
EXAMPLES::
370
371
sage: P2 = toric_varieties.P2()
372
sage: dP8 = toric_varieties.dP8()
373
sage: f = dP8.hom(identity_matrix(2), P2); f
374
Scheme morphism:
375
From: 2-d CPR-Fano toric variety covered by 4 affine patches
376
To: 2-d CPR-Fano toric variety covered by 3 affine patches
377
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
378
to Rational polyhedral fan in 2-d lattice N.
379
sage: type(f)
380
<class 'sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety'>
381
382
Slightly more explicit construction::
383
384
sage: P1xP1 = toric_varieties.P1xP1()
385
sage: P1 = toric_varieties.P1()
386
sage: hom_set = P1xP1.Hom(P1)
387
sage: fm = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() )
388
sage: hom_set(fm)
389
Scheme morphism:
390
From: 2-d CPR-Fano toric variety covered by 4 affine patches
391
To: 1-d CPR-Fano toric variety covered by 2 affine patches
392
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
393
to Rational polyhedral fan in 1-d lattice N.
394
395
sage: P1xP1.hom(fm, P1)
396
Scheme morphism:
397
From: 2-d CPR-Fano toric variety covered by 4 affine patches
398
To: 1-d CPR-Fano toric variety covered by 2 affine patches
399
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
400
to Rational polyhedral fan in 1-d lattice N.
401
"""
402
403
def __init__(self, parent, fan_morphism, check=True):
404
r"""
405
See :class:`SchemeMorphism_polynomial_toric_variety` for documentation.
406
407
TESTS::
408
409
sage: P1xP1 = toric_varieties.P1xP1()
410
sage: P1 = toric_varieties.P1()
411
sage: hom_set = P1xP1.Hom(P1)
412
sage: fan_morphism = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() )
413
sage: from sage.schemes.toric.morphism import SchemeMorphism_fan_toric_variety
414
sage: SchemeMorphism_fan_toric_variety(hom_set, fan_morphism)
415
Scheme morphism:
416
From: 2-d CPR-Fano toric variety covered by 4 affine patches
417
To: 1-d CPR-Fano toric variety covered by 2 affine patches
418
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
419
to Rational polyhedral fan in 1-d lattice N.
420
"""
421
SchemeMorphism.__init__(self, parent)
422
if check and self.domain().fan()!=fan_morphism.domain_fan():
423
raise ValueError('The fan morphism domain must be the fan of the domain.')
424
if check and self.codomain().fan()!=fan_morphism.codomain_fan():
425
raise ValueError('The fan morphism codomain must be the fan of the codomain.')
426
self._fan_morphism = fan_morphism
427
428
def _repr_defn(self):
429
"""
430
Return a string representation of the definition of ``self``.
431
432
OUTPUT:
433
434
String.
435
436
EXAMPLES::
437
438
sage: P1xP1 = toric_varieties.P1xP1()
439
sage: P1 = toric_varieties.P1()
440
sage: f = P1xP1.hom(matrix([[1],[0]]), P1)
441
sage: f._repr_defn()
442
'Defined by sending Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 1-d lattice N.'
443
"""
444
s = 'Defined by sending '
445
s += str(self.domain().fan())
446
s += ' to '
447
s += str(self.codomain().fan())
448
s += '.'
449
return s
450
451
def fan_morphism(self):
452
"""
453
Return the defining fan morphism.
454
455
OUTPUT:
456
457
A :class:`~sage.geometry.fan_morphism.FanMorphism`.
458
459
EXAMPLES::
460
461
sage: P1xP1 = toric_varieties.P1xP1()
462
sage: P1 = toric_varieties.P1()
463
sage: f = P1xP1.hom(matrix([[1],[0]]), P1)
464
sage: f.fan_morphism()
465
Fan morphism defined by the matrix
466
[1]
467
[0]
468
Domain fan: Rational polyhedral fan in 2-d lattice N
469
Codomain fan: Rational polyhedral fan in 1-d lattice N
470
"""
471
return self._fan_morphism
472
473
def as_polynomial_map(self):
474
"""
475
Express the morphism via homogeneous polynomials.
476
477
OUTPUT:
478
479
A :class:`SchemeMorphism_polynomial_toric_variety`. Raises a
480
``TypeError`` if the morphism cannot be written in terms of
481
homogeneous polynomials.
482
483
EXAMPLES::
484
485
sage: A1 = toric_varieties.A1()
486
sage: square = A1.hom(matrix([[2]]), A1)
487
sage: square.as_polynomial_map()
488
Scheme endomorphism of 1-d affine toric variety
489
Defn: Defined on coordinates by sending [z] to
490
[z^2]
491
492
sage: P1 = toric_varieties.P1()
493
sage: patch = A1.hom(matrix([[1]]), P1)
494
sage: patch.as_polynomial_map()
495
Scheme morphism:
496
From: 1-d affine toric variety
497
To: 1-d CPR-Fano toric variety covered by 2 affine patches
498
Defn: Defined on coordinates by sending [z] to
499
[z : 1]
500
"""
501
R = self.domain().coordinate_ring()
502
phi = self.fan_morphism()
503
polys = [R.one()] * phi.codomain_fan().nrays()
504
for rho, x in zip(phi.domain_fan(1), R.gens()):
505
ray = rho.ray(0)
506
sigma = phi.image_cone(rho)
507
degrees = sigma.ray_matrix().solve_right(phi(ray))
508
for i, d in zip(sigma.ambient_ray_indices(), degrees):
509
try:
510
d = ZZ(d)
511
except TypeError:
512
raise TypeError('The fan morphism cannot be written in homogeneous polynomials.')
513
polys[i] *= x**d
514
return SchemeMorphism_polynomial_toric_variety(self.parent(), polys)
515
516
517