Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/toric/morphism.py
8820 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),
127
N(1, 2)
128
in 2-d lattice N
129
sage: O2_P1 = A2_Z2.resolve(new_rays=[(1,1)])
130
sage: blowup = O2_P1.hom(identity_matrix(2), A2_Z2)
131
sage: blowup.as_polynomial_map()
132
Traceback (most recent call last):
133
...
134
TypeError: The fan morphism cannot be written in homogeneous polynomials.
135
136
If we denote the homogeneous coordinates of `O_{\mathbb{P}^1}(2)` by
137
`x`, `t`, `y` corresponding to the rays `(1,2)`, `(1,1)`, and `(1,0)`
138
then the blow-up map is [BB]_:
139
140
.. math::
141
142
f: O_{\mathbb{P}^1}(2) \to \CC^2/\ZZ_2, \quad
143
(x,t,y) \mapsto \left( x\sqrt{t}, y\sqrt{t} \right)
144
145
which requires square roots.
146
147
REFERENCES:
148
149
.. [BB]
150
Gavin Brown, Jaroslaw Buczynski:
151
Maps of toric varieties in Cox coordinates,
152
http://arxiv.org/abs/1004.4924
153
"""
154
155
156
#*****************************************************************************
157
# Copyright (C) 2011 Volker Braun <[email protected]>
158
# Copyright (C) 2010 Andrey Novoseltsev <[email protected]>
159
# Copyright (C) 2006 William Stein <[email protected]>
160
# Distributed under the terms of the GNU General Public License (GPL)
161
# http://www.gnu.org/licenses/
162
#*****************************************************************************
163
164
# For now, the scheme morphism base class cannot derive from Morphism
165
# since this would clash with elliptic curves. So we derive only on
166
# the toric varieties level from Morphism. See
167
# https://groups.google.com/d/msg/sage-devel/qF4yU6Vdmao/wQlNrneSmWAJ
168
from sage.categories.morphism import Morphism
169
170
from sage.structure.sequence import Sequence
171
from sage.rings.all import ZZ
172
173
from sage.schemes.generic.scheme import is_Scheme
174
from sage.schemes.generic.morphism import (
175
is_SchemeMorphism,
176
SchemeMorphism, SchemeMorphism_point, SchemeMorphism_polynomial
177
)
178
179
180
181
############################################################################
182
# A points on a toric variety determined by homogeneous coordinates.
183
class SchemeMorphism_point_toric_field(SchemeMorphism_point, Morphism):
184
"""
185
A point of a toric variety determined by homogeneous coordinates
186
in a field.
187
188
.. WARNING::
189
190
You should not create objects of this class directly. Use the
191
:meth:`~sage.schemes.generic.scheme.hom` method of
192
:class:`toric varieties
193
<sage.schemes.toric.variety.ToricVariety_field>`
194
instead.
195
196
INPUT:
197
198
- ``X`` -- toric variety or subscheme of a toric variety.
199
200
- ``coordinates`` -- list of coordinates in the base field of ``X``.
201
202
- ``check`` -- if ``True`` (default), the input will be checked for
203
correctness.
204
205
OUTPUT:
206
207
A :class:`SchemeMorphism_point_toric_field`.
208
209
TESTS::
210
211
sage: fan = FaceFan(lattice_polytope.octahedron(2))
212
sage: P1xP1 = ToricVariety(fan)
213
sage: P1xP1(1,2,3,4)
214
[1 : 2 : 3 : 4]
215
"""
216
# Mimicking affine/projective classes
217
def __init__(self, X, coordinates, check=True):
218
r"""
219
See :class:`SchemeMorphism_point_toric_field` for documentation.
220
221
TESTS::
222
223
sage: fan = FaceFan(lattice_polytope.octahedron(2))
224
sage: P1xP1 = ToricVariety(fan)
225
sage: P1xP1(1,2,3,4)
226
[1 : 2 : 3 : 4]
227
"""
228
# Convert scheme to its set of points over the base ring
229
if is_Scheme(X):
230
X = X(X.base_ring())
231
super(SchemeMorphism_point_toric_field, self).__init__(X)
232
if check:
233
# Verify that there are the right number of coords
234
# Why is it not done in the parent?
235
if is_SchemeMorphism(coordinates):
236
coordinates = list(coordinates)
237
if not isinstance(coordinates, (list, tuple)):
238
raise TypeError("coordinates must be a scheme point, list, "
239
"or tuple. Got %s" % coordinates)
240
d = X.codomain().ambient_space().ngens()
241
if len(coordinates) != d:
242
raise ValueError("there must be %d coordinates! Got only %d: "
243
"%s" % (d, len(coordinates), coordinates))
244
# Make sure the coordinates all lie in the appropriate ring
245
coordinates = Sequence(coordinates, X.value_ring())
246
# Verify that the point satisfies the equations of X.
247
X.codomain()._check_satisfies_equations(coordinates)
248
self._coords = coordinates
249
250
251
252
############################################################################
253
# A morphism of toric varieties determined by homogeneous polynomials.
254
class SchemeMorphism_polynomial_toric_variety(SchemeMorphism_polynomial, Morphism):
255
"""
256
A morphism determined by homogeneous polynomials.
257
258
.. WARNING::
259
260
You should not create objects of this class directly. Use the
261
:meth:`~sage.schemes.generic.scheme.hom` method of
262
:class:`toric varieties
263
<sage.schemes.toric.variety.ToricVariety_field>`
264
instead.
265
266
INPUT:
267
268
Same as for
269
:class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial`.
270
271
OUPUT:
272
273
A :class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety`.
274
275
TESTS::
276
277
sage: fan = FaceFan(lattice_polytope.octahedron(2))
278
sage: P1xP1 = ToricVariety(fan)
279
sage: P1xP1.inject_variables()
280
Defining z0, z1, z2, z3
281
sage: P1 = P1xP1.subscheme(z0-z2)
282
sage: H = P1xP1.Hom(P1)
283
sage: import sage.schemes.toric.morphism as MOR
284
sage: MOR.SchemeMorphism_polynomial_toric_variety(H, [z0,z1,z0,z3])
285
Scheme morphism:
286
From: 2-d toric variety covered by 4 affine patches
287
To: Closed subscheme of 2-d toric variety
288
covered by 4 affine patches defined by:
289
z0 - z2
290
Defn: Defined on coordinates by sending
291
[z0 : z1 : z2 : z3] to [z0 : z1 : z0 : z3]
292
"""
293
294
def __init__(self, parent, polynomials, check=True):
295
r"""
296
See :class:`SchemeMorphism_polynomial_toric_variety` for documentation.
297
298
TESTS::
299
300
sage: fan = FaceFan(lattice_polytope.octahedron(2))
301
sage: P1xP1 = ToricVariety(fan)
302
sage: P1xP1.inject_variables()
303
Defining z0, z1, z2, z3
304
sage: P1 = P1xP1.subscheme(z0-z2)
305
sage: H = P1xP1.Hom(P1)
306
sage: import sage.schemes.toric.morphism as MOR
307
sage: MOR.SchemeMorphism_polynomial_toric_variety(H, [z0,z1,z0,z3])
308
Scheme morphism:
309
From: 2-d toric variety covered by 4 affine patches
310
To: Closed subscheme of 2-d toric variety
311
covered by 4 affine patches defined by:
312
z0 - z2
313
Defn: Defined on coordinates by sending
314
[z0 : z1 : z2 : z3] to [z0 : z1 : z0 : z3]
315
"""
316
SchemeMorphism_polynomial.__init__(self, parent, polynomials, check)
317
if check:
318
# Check that defining polynomials are homogeneous (degrees can be
319
# different if the target uses weighted coordinates)
320
for p in self.defining_polynomials():
321
if not self.domain().ambient_space().is_homogeneous(p):
322
raise ValueError("%s is not homogeneous!" % p)
323
324
def as_fan_morphism(self):
325
"""
326
Express the morphism as a map defined by a fan morphism.
327
328
OUTPUT:
329
330
A :class:`SchemeMorphism_polynomial_toric_variety`. Raises a
331
``TypeError`` if the morphism cannot be written in such a way.
332
333
EXAMPLES::
334
335
sage: A1.<z> = toric_varieties.A1()
336
sage: P1 = toric_varieties.P1()
337
sage: patch = A1.hom([1,z], P1)
338
sage: patch.as_fan_morphism()
339
Traceback (most recent call last):
340
...
341
NotImplementedError: expressing toric morphisms as fan morphisms is
342
not implemented yet!
343
"""
344
raise NotImplementedError("expressing toric morphisms as fan "
345
"morphisms is not implemented yet!")
346
347
348
############################################################################
349
# A morphism of toric varieties determined by a fan morphism
350
class SchemeMorphism_fan_toric_variety(SchemeMorphism, Morphism):
351
"""
352
Construct a morphism determined by a fan morphism
353
354
.. WARNING::
355
356
You should not create objects of this class directly. Use the
357
:meth:`~sage.schemes.generic.scheme.hom` method of
358
:class:`toric varieties
359
<sage.schemes.toric.variety.ToricVariety_field>`
360
instead.
361
362
INPUT:
363
364
- ``parent`` -- Hom-set whose domain and codomain are toric varieties.
365
366
- ``fan_morphism`` -- A morphism of fans whose domain and codomain
367
fans equal the fans of the domain and codomain in the ``parent``
368
Hom-set.
369
370
- ``check`` -- boolean (optional, default:``True``). Whether to
371
check the input for consistency.
372
373
OUPUT:
374
375
A :class:`~sage.schemes.generic.morphism.SchemeMorphism_fan_toric_variety`.
376
377
EXAMPLES::
378
379
sage: P2 = toric_varieties.P2()
380
sage: dP8 = toric_varieties.dP8()
381
sage: f = dP8.hom(identity_matrix(2), P2); f
382
Scheme morphism:
383
From: 2-d CPR-Fano toric variety covered by 4 affine patches
384
To: 2-d CPR-Fano toric variety covered by 3 affine patches
385
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
386
to Rational polyhedral fan in 2-d lattice N.
387
sage: type(f)
388
<class 'sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety'>
389
390
Slightly more explicit construction::
391
392
sage: P1xP1 = toric_varieties.P1xP1()
393
sage: P1 = toric_varieties.P1()
394
sage: hom_set = P1xP1.Hom(P1)
395
sage: fm = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() )
396
sage: hom_set(fm)
397
Scheme morphism:
398
From: 2-d CPR-Fano toric variety covered by 4 affine patches
399
To: 1-d CPR-Fano toric variety covered by 2 affine patches
400
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
401
to Rational polyhedral fan in 1-d lattice N.
402
403
sage: P1xP1.hom(fm, P1)
404
Scheme morphism:
405
From: 2-d CPR-Fano toric variety covered by 4 affine patches
406
To: 1-d CPR-Fano toric variety covered by 2 affine patches
407
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
408
to Rational polyhedral fan in 1-d lattice N.
409
"""
410
411
def __init__(self, parent, fan_morphism, check=True):
412
r"""
413
See :class:`SchemeMorphism_polynomial_toric_variety` for documentation.
414
415
TESTS::
416
417
sage: P1xP1 = toric_varieties.P1xP1()
418
sage: P1 = toric_varieties.P1()
419
sage: hom_set = P1xP1.Hom(P1)
420
sage: fan_morphism = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() )
421
sage: from sage.schemes.toric.morphism import SchemeMorphism_fan_toric_variety
422
sage: SchemeMorphism_fan_toric_variety(hom_set, fan_morphism)
423
Scheme morphism:
424
From: 2-d CPR-Fano toric variety covered by 4 affine patches
425
To: 1-d CPR-Fano toric variety covered by 2 affine patches
426
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
427
to Rational polyhedral fan in 1-d lattice N.
428
"""
429
SchemeMorphism.__init__(self, parent)
430
if check and self.domain().fan()!=fan_morphism.domain_fan():
431
raise ValueError('The fan morphism domain must be the fan of the domain.')
432
if check and self.codomain().fan()!=fan_morphism.codomain_fan():
433
raise ValueError('The fan morphism codomain must be the fan of the codomain.')
434
self._fan_morphism = fan_morphism
435
436
def __cmp__(self, right):
437
r"""
438
Compare ``self`` and ``right``.
439
440
INPUT:
441
442
- ``right`` -- anything.
443
444
OUTPUT:
445
446
- 0 if ``right`` is also a toric morphism between the same domain and
447
codomain, given by an equal fan morphism. 1 or -1 otherwise.
448
449
TESTS::
450
451
sage: A2 = toric_varieties.A2()
452
sage: P3 = toric_varieties.P(3)
453
sage: m = matrix([(2,0,0), (1,1,0)])
454
sage: phi = A2.hom(m, P3)
455
sage: cmp(phi, phi)
456
0
457
sage: cmp(phi, prod(phi.factor()))
458
0
459
sage: abs(cmp(phi, phi.factor()[0]))
460
1
461
sage: cmp(phi, 1) * cmp(1, phi)
462
-1
463
"""
464
if isinstance(right, SchemeMorphism_fan_toric_variety):
465
return cmp(
466
[self.domain(), self.codomain(), self.fan_morphism()],
467
[right.domain(), right.codomain(), right.fan_morphism()])
468
else:
469
return cmp(type(self), type(right))
470
471
def _composition_(self, right, homset):
472
"""
473
Return the composition of ``self`` and ``right``.
474
475
INPUT:
476
477
- ``right`` -- a toric morphism defined by a fan morphism.
478
479
OUTPUT:
480
481
- a toric morphism.
482
483
EXAMPLES::
484
485
sage: A2 = toric_varieties.A2()
486
sage: P3 = toric_varieties.P(3)
487
sage: m = matrix([(2,0,0), (1,1,0)])
488
sage: phi = A2.hom(m, P3)
489
sage: phi1, phi2, phi3 = phi.factor()
490
sage: phi1 * phi2
491
Scheme morphism:
492
From: 2-d affine toric variety
493
To: 3-d CPR-Fano toric variety covered by 4 affine patches
494
Defn: Defined by sending Rational polyhedral fan in Sublattice
495
<N(1, 0, 0), N(0, 1, 0)> to Rational polyhedral fan in 3-d lattice N.
496
sage: phi1 * phi2 * phi3 == phi
497
True
498
"""
499
f = self.fan_morphism() * right.fan_morphism()
500
return homset(f, self.codomain())
501
502
def _repr_defn(self):
503
"""
504
Return a string representation of the definition of ``self``.
505
506
OUTPUT:
507
508
String.
509
510
EXAMPLES::
511
512
sage: P1xP1 = toric_varieties.P1xP1()
513
sage: P1 = toric_varieties.P1()
514
sage: f = P1xP1.hom(matrix([[1],[0]]), P1)
515
sage: f._repr_defn()
516
'Defined by sending Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 1-d lattice N.'
517
"""
518
s = 'Defined by sending '
519
s += str(self.domain().fan())
520
s += ' to '
521
s += str(self.codomain().fan())
522
s += '.'
523
return s
524
525
def factor(self):
526
r"""
527
Factor ``self`` into injective * birational * surjective morphisms.
528
529
OUTPUT:
530
531
- a triple of toric morphisms `(\phi_i, \phi_b, \phi_s)`, such that
532
`\phi_s` is surjective, `\phi_b` is birational, `\phi_i` is injective,
533
and ``self`` is equal to `\phi_i \circ \phi_b \circ \phi_s`.
534
535
The intermediate varieties are universal in the following sense. Let
536
``self`` map `X` to `X'` and let `X_s`, `X_i` seat in between, i.e.
537
538
.. math::
539
540
X
541
\twoheadrightarrow
542
X_s
543
\to
544
X_i
545
\hookrightarrow
546
X'.
547
548
Then any toric morphism from `X` coinciding with ``self`` on the maximal
549
torus factors through `X_s` and any toric morphism into `X'` coinciding
550
with ``self`` on the maximal torus factors through `X_i`. In particular,
551
`X_i` is the closure of the image of ``self`` in `X'`.
552
553
See
554
:meth:`~sage.geometry.fan_morphism.FanMorphism.factor`
555
for a description of the toric algorithm.
556
557
EXAMPLES:
558
559
We map an affine plane into a projective 3-space in such a way, that it
560
becomes "a double cover of a chart of the blow up of one of the
561
coordinate planes"::
562
563
sage: A2 = toric_varieties.A2()
564
sage: P3 = toric_varieties.P(3)
565
sage: m = matrix([(2,0,0), (1,1,0)])
566
sage: phi = A2.hom(m, P3)
567
sage: phi.as_polynomial_map()
568
Scheme morphism:
569
From: 2-d affine toric variety
570
To: 3-d CPR-Fano toric variety covered by 4 affine patches
571
Defn: Defined on coordinates by sending [x : y] to
572
[x^2*y : y : 1 : 1]
573
574
sage: phi.is_surjective(), phi.is_birational(), phi.is_injective()
575
(False, False, False)
576
sage: phi_i, phi_b, phi_s = phi.factor()
577
sage: phi_s.is_surjective(), phi_b.is_birational(), phi_i.is_injective()
578
(True, True, True)
579
sage: prod(phi.factor()) == phi
580
True
581
582
Double cover (surjective)::
583
584
sage: phi_s.as_polynomial_map()
585
Scheme morphism:
586
From: 2-d affine toric variety
587
To: 2-d affine toric variety
588
Defn: Defined on coordinates by sending [x : y] to
589
[x^2 : y]
590
591
Blowup chart (birational)::
592
593
sage: phi_b.as_polynomial_map()
594
Scheme morphism:
595
From: 2-d affine toric variety
596
To: 2-d toric variety covered by 3 affine patches
597
Defn: Defined on coordinates by sending [z0 : z1] to
598
[z0*z1 : z1 : 1]
599
600
Coordinate plane inclusion (injective)::
601
602
sage: phi_i.as_polynomial_map()
603
Scheme morphism:
604
From: 2-d toric variety covered by 3 affine patches
605
To: 3-d CPR-Fano toric variety covered by 4 affine patches
606
Defn: Defined on coordinates by sending [z0 : z1 : z2] to
607
[z0 : z1 : z2 : z2]
608
"""
609
phi_i, phi_b, phi_s = self.fan_morphism().factor()
610
from sage.schemes.toric.all import ToricVariety
611
X = self.domain()
612
X_s = ToricVariety(phi_s.codomain_fan())
613
X_i = ToricVariety(phi_i.domain_fan())
614
X_prime = self.codomain()
615
return X_i.hom(phi_i, X_prime), X_s.hom(phi_b, X_i), X.hom(phi_s, X_s)
616
617
def fan_morphism(self):
618
"""
619
Return the defining fan morphism.
620
621
OUTPUT:
622
623
A :class:`~sage.geometry.fan_morphism.FanMorphism`.
624
625
EXAMPLES::
626
627
sage: P1xP1 = toric_varieties.P1xP1()
628
sage: P1 = toric_varieties.P1()
629
sage: f = P1xP1.hom(matrix([[1],[0]]), P1)
630
sage: f.fan_morphism()
631
Fan morphism defined by the matrix
632
[1]
633
[0]
634
Domain fan: Rational polyhedral fan in 2-d lattice N
635
Codomain fan: Rational polyhedral fan in 1-d lattice N
636
"""
637
return self._fan_morphism
638
639
def as_polynomial_map(self):
640
"""
641
Express the morphism via homogeneous polynomials.
642
643
OUTPUT:
644
645
A :class:`SchemeMorphism_polynomial_toric_variety`. Raises a
646
``TypeError`` if the morphism cannot be written in terms of
647
homogeneous polynomials.
648
649
EXAMPLES::
650
651
sage: A1 = toric_varieties.A1()
652
sage: square = A1.hom(matrix([[2]]), A1)
653
sage: square.as_polynomial_map()
654
Scheme endomorphism of 1-d affine toric variety
655
Defn: Defined on coordinates by sending [z] to
656
[z^2]
657
658
sage: P1 = toric_varieties.P1()
659
sage: patch = A1.hom(matrix([[1]]), P1)
660
sage: patch.as_polynomial_map()
661
Scheme morphism:
662
From: 1-d affine toric variety
663
To: 1-d CPR-Fano toric variety covered by 2 affine patches
664
Defn: Defined on coordinates by sending [z] to
665
[z : 1]
666
"""
667
R = self.domain().coordinate_ring()
668
phi = self.fan_morphism()
669
polys = [R.one()] * phi.codomain_fan().nrays()
670
for rho, x in zip(phi.domain_fan(1), R.gens()):
671
ray = rho.ray(0)
672
sigma = phi.image_cone(rho)
673
degrees = sigma.rays().matrix().solve_left(phi(ray))
674
for i, d in zip(sigma.ambient_ray_indices(), degrees):
675
try:
676
d = ZZ(d)
677
except TypeError:
678
raise TypeError('The fan morphism cannot be written in homogeneous polynomials.')
679
polys[i] *= x**d
680
return SchemeMorphism_polynomial_toric_variety(self.parent(), polys)
681
682
def is_birational(self):
683
r"""
684
Check if ``self`` is birational.
685
686
See
687
:meth:`~sage.geometry.fan_morphism.FanMorphism.is_birational`
688
for a description of the toric algorithm.
689
690
OUTPUT:
691
692
Boolean. Whether ``self`` is birational.
693
694
EXAMPLES::
695
696
sage: X = toric_varieties.A(2)
697
sage: Y = ToricVariety(Fan([Cone([(1,0), (1,1)])]))
698
sage: m = identity_matrix(2)
699
sage: f = Y.hom(m, X)
700
sage: f.is_birational()
701
True
702
"""
703
return self.fan_morphism().is_birational()
704
705
def is_injective(self):
706
r"""
707
Check if ``self`` is injective.
708
709
See
710
:meth:`~sage.geometry.fan_morphism.FanMorphism.is_injective`
711
for a description of the toric algorithm.
712
713
OUTPUT:
714
715
Boolean. Whether ``self`` is injective.
716
717
EXAMPLES::
718
719
sage: X = toric_varieties.A(2)
720
sage: m = identity_matrix(2)
721
sage: f = X.hom(m, X)
722
sage: f.is_injective()
723
True
724
725
sage: Y = ToricVariety(Fan([Cone([(1,0), (1,1)])]))
726
sage: f = Y.hom(m, X)
727
sage: f.is_injective()
728
False
729
"""
730
return self.fan_morphism().is_injective()
731
732
def is_surjective(self):
733
r"""
734
Check if ``self`` is surjective.
735
736
See
737
:meth:`~sage.geometry.fan_morphism.FanMorphism.is_surjective`
738
for a description of the toric algorithm.
739
740
OUTPUT:
741
742
Boolean. Whether ``self`` is surjective.
743
744
EXAMPLES::
745
746
sage: X = toric_varieties.A(2)
747
sage: m = identity_matrix(2)
748
sage: f = X.hom(m, X)
749
sage: f.is_surjective()
750
True
751
752
sage: Y = ToricVariety(Fan([Cone([(1,0), (1,1)])]))
753
sage: f = Y.hom(m, X)
754
sage: f.is_surjective()
755
False
756
"""
757
return self.fan_morphism().is_surjective()
758
759