Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/toric/homset.py
8820 views
1
r"""
2
Set of homomorphisms between two toric varieties.
3
4
For schemes `X` and `Y`, this module implements the set of morphisms
5
`Hom(X,Y)`. This is done by
6
:class:`~sage.schemes.generic.homset.SchemeHomset_generic`.
7
8
As a special case, the Hom-sets can also represent the points of a
9
scheme. Recall that the `K`-rational points of a scheme `X` over `k`
10
can be identified with the set of morphisms `Spec(K) \to X`. In Sage,
11
the rational points are implemented by such scheme morphisms. This is
12
done by :class:`~sage.schemes.generic.homset.SchemeHomset_points` and
13
its subclasses.
14
15
.. note::
16
17
You should not create the Hom-sets manually. Instead, use the
18
:meth:`~sage.structure.parent.Hom` method that is inherited by all
19
schemes.
20
21
AUTHORS:
22
23
- Volker Braun (2012-02-18): Initial version
24
25
EXAMPLES:
26
27
Here is a simple example, the projection of
28
`\mathbb{P}^1\times\mathbb{P}^1\to \mathbb{P}^1` ::
29
30
sage: P1xP1 = toric_varieties.P1xP1()
31
sage: P1 = toric_varieties.P1()
32
sage: hom_set = P1xP1.Hom(P1); hom_set
33
Set of morphisms
34
From: 2-d CPR-Fano toric variety covered by 4 affine patches
35
To: 1-d CPR-Fano toric variety covered by 2 affine patches
36
37
In terms of the fan, we can define this morphism by the projection
38
onto the first coordinate. The Hom-set can construct the morphism from
39
the projection matrix alone::
40
41
sage: hom_set(matrix([[1],[0]]))
42
Scheme morphism:
43
From: 2-d CPR-Fano toric variety covered by 4 affine patches
44
To: 1-d CPR-Fano toric variety covered by 2 affine patches
45
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
46
to Rational polyhedral fan in 1-d lattice N.
47
sage: _.as_polynomial_map()
48
Scheme morphism:
49
From: 2-d CPR-Fano toric variety covered by 4 affine patches
50
To: 1-d CPR-Fano toric variety covered by 2 affine patches
51
Defn: Defined on coordinates by sending [s : t : x : y] to
52
[s : t]
53
54
In the case of toric algebraic schemes (defined by polynomials in
55
toric varieties), this module defines the underlying morphism of the
56
ambient toric varieties::
57
58
sage: P1xP1.inject_variables()
59
Defining s, t, x, y
60
sage: S = P1xP1.subscheme([s*x-t*y])
61
sage: type(S.Hom(S))
62
<class 'sage.schemes.toric.homset.SchemeHomset_toric_variety_with_category'>
63
64
Finally, you can have morphisms defined through homogeneous
65
coordinates where the codomain is not implemented as a toric variety::
66
67
sage: P2_toric.<x,y,z> = toric_varieties.P2()
68
sage: P2_native.<u,v,w> = ProjectiveSpace(QQ, 2)
69
sage: toric_to_native = P2_toric.Hom(P2_native); toric_to_native
70
Set of morphisms
71
From: 2-d CPR-Fano toric variety covered by 3 affine patches
72
To: Projective Space of dimension 2 over Rational Field
73
sage: type(toric_to_native)
74
<class 'sage.schemes.toric.homset.SchemeHomset_toric_variety_with_category'>
75
sage: toric_to_native([x^2, y^2, z^2])
76
Scheme morphism:
77
From: 2-d CPR-Fano toric variety covered by 3 affine patches
78
To: Projective Space of dimension 2 over Rational Field
79
Defn: Defined on coordinates by sending [x : y : z] to
80
(x^2 : y^2 : z^2)
81
82
sage: native_to_toric = P2_native.Hom(P2_toric); native_to_toric
83
Set of morphisms
84
From: Projective Space of dimension 2 over Rational Field
85
To: 2-d CPR-Fano toric variety covered by 3 affine patches
86
sage: type(native_to_toric)
87
<class 'sage.schemes.generic.homset.SchemeHomset_generic_with_category'>
88
sage: native_to_toric([u^2, v^2, w^2])
89
Scheme morphism:
90
From: Projective Space of dimension 2 over Rational Field
91
To: 2-d CPR-Fano toric variety covered by 3 affine patches
92
Defn: Defined on coordinates by sending (u : v : w) to
93
[u^2 : v^2 : w^2]
94
"""
95
96
97
98
#*****************************************************************************
99
# Copyright (C) 2010 Volker Braun <[email protected]>
100
# Copyright (C) 2010 Andrey Novoseltsev <[email protected]>
101
#
102
# Distributed under the terms of the GNU General Public License (GPL)
103
# as published by the Free Software Foundation; either version 2 of
104
# the License, or (at your option) any later version.
105
# http://www.gnu.org/licenses/
106
#*****************************************************************************
107
108
109
from sage.rings.all import ZZ
110
from sage.rings.morphism import is_RingHomomorphism
111
112
from sage.matrix.matrix import is_Matrix
113
from sage.matrix.matrix_space import MatrixSpace
114
from sage.geometry.fan_morphism import FanMorphism
115
116
from sage.schemes.generic.homset import (SchemeHomset_generic,
117
SchemeHomset_points)
118
119
120
class SchemeHomset_toric_variety(SchemeHomset_generic):
121
"""
122
Set of homomorphisms between two toric varieties.
123
124
EXAMPLES::
125
126
sage: P1xP1 = toric_varieties.P1xP1()
127
sage: P1 = toric_varieties.P1()
128
sage: hom_set = P1xP1.Hom(P1); hom_set
129
Set of morphisms
130
From: 2-d CPR-Fano toric variety covered by 4 affine patches
131
To: 1-d CPR-Fano toric variety covered by 2 affine patches
132
sage: type(hom_set)
133
<class 'sage.schemes.toric.homset.SchemeHomset_toric_variety_with_category'>
134
135
sage: hom_set(matrix([[1],[0]]))
136
Scheme morphism:
137
From: 2-d CPR-Fano toric variety covered by 4 affine patches
138
To: 1-d CPR-Fano toric variety covered by 2 affine patches
139
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
140
to Rational polyhedral fan in 1-d lattice N.
141
"""
142
143
def __init__(self, X, Y, category=None, check=True, base=ZZ):
144
"""
145
The Python constructor.
146
147
INPUT:
148
149
The same as for any homset, see
150
:mod:`~sage.categories.homset`.
151
152
EXAMPLES::
153
154
sage: P1xP1 = toric_varieties.P1xP1()
155
sage: P1 = toric_varieties.P1()
156
sage: hom_set = P1xP1.Hom(P1); hom_set
157
Set of morphisms
158
From: 2-d CPR-Fano toric variety covered by 4 affine patches
159
To: 1-d CPR-Fano toric variety covered by 2 affine patches
160
161
An integral matrix defines a fan morphism, since we think of
162
the matrix as a linear map on the toric lattice. This is why
163
we need to ``register_conversion`` in the constructor
164
below. The result is::
165
166
sage: hom_set(matrix([[1],[0]]))
167
Scheme morphism:
168
From: 2-d CPR-Fano toric variety covered by 4 affine patches
169
To: 1-d CPR-Fano toric variety covered by 2 affine patches
170
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
171
to Rational polyhedral fan in 1-d lattice N.
172
"""
173
SchemeHomset_generic.__init__(self, X, Y, category=category, check=check, base=base)
174
from sage.schemes.toric.variety import is_ToricVariety
175
if is_ToricVariety(X) and is_ToricVariety(Y):
176
self.register_conversion(MatrixSpace(ZZ, X.fan().dim(), Y.fan().dim()))
177
178
def _element_constructor_(self, x, check=True):
179
"""
180
Construct a scheme morphism.
181
182
INPUT:
183
184
- `x` -- anything that defines a morphism of toric
185
varieties. A matrix, fan morphism, or a list or tuple of
186
homogeneous polynomials that define a morphism.
187
188
- ``check`` -- boolean (default: ``True``) passed onto
189
functions called by this to be more careful about input
190
argument type checking
191
192
OUTPUT:
193
194
The morphism of toric varieties determined by ``x``.
195
196
EXAMPLES:
197
198
First, construct from fan morphism::
199
200
sage: dP8.<t,x0,x1,x2> = toric_varieties.dP8()
201
sage: P2.<y0,y1,y2> = toric_varieties.P2()
202
sage: hom_set = dP8.Hom(P2)
203
204
sage: fm = FanMorphism(identity_matrix(2), dP8.fan(), P2.fan())
205
sage: hom_set(fm) # calls hom_set._element_constructor_()
206
Scheme morphism:
207
From: 2-d CPR-Fano toric variety covered by 4 affine patches
208
To: 2-d CPR-Fano toric variety covered by 3 affine patches
209
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
210
to Rational polyhedral fan in 2-d lattice N.
211
212
A matrix will automatically be converted to a fan morphism::
213
214
sage: hom_set(identity_matrix(2))
215
Scheme morphism:
216
From: 2-d CPR-Fano toric variety covered by 4 affine patches
217
To: 2-d CPR-Fano toric variety covered by 3 affine patches
218
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N
219
to Rational polyhedral fan in 2-d lattice N.
220
221
Alternatively, one can use homogeneous polynomials to define morphisms::
222
223
sage: P2.inject_variables()
224
Defining y0, y1, y2
225
sage: dP8.inject_variables()
226
Defining t, x0, x1, x2
227
sage: hom_set([x0,x1,x2])
228
Scheme morphism:
229
From: 2-d CPR-Fano toric variety covered by 4 affine patches
230
To: 2-d CPR-Fano toric variety covered by 3 affine patches
231
Defn: Defined on coordinates by sending [t : x0 : x1 : x2] to
232
[x0 : x1 : x2]
233
234
A morphism of the coordinate ring will also work::
235
236
sage: ring_hom = P2.coordinate_ring().hom([x0,x1,x2], dP8.coordinate_ring())
237
sage: ring_hom
238
Ring morphism:
239
From: Multivariate Polynomial Ring in y0, y1, y2 over Rational Field
240
To: Multivariate Polynomial Ring in t, x0, x1, x2 over Rational Field
241
Defn: y0 |--> x0
242
y1 |--> x1
243
y2 |--> x2
244
sage: hom_set(ring_hom)
245
Scheme morphism:
246
From: 2-d CPR-Fano toric variety covered by 4 affine patches
247
To: 2-d CPR-Fano toric variety covered by 3 affine patches
248
Defn: Defined on coordinates by sending [t : x0 : x1 : x2] to
249
[x0 : x1 : x2]
250
"""
251
from sage.schemes.toric.morphism import SchemeMorphism_polynomial_toric_variety
252
if isinstance(x, (list, tuple)):
253
return SchemeMorphism_polynomial_toric_variety(self, x, check=check)
254
255
if is_RingHomomorphism(x):
256
assert x.domain() is self.codomain().coordinate_ring()
257
assert x.codomain() is self.domain().coordinate_ring()
258
return SchemeMorphism_polynomial_toric_variety(self, x.im_gens(), check=check)
259
260
from sage.schemes.toric.morphism import SchemeMorphism_fan_toric_variety
261
if isinstance(x, FanMorphism):
262
return SchemeMorphism_fan_toric_variety(self, x, check=check)
263
264
if is_Matrix(x):
265
fm = FanMorphism(x, self.domain().fan(), self.codomain().fan())
266
return SchemeMorphism_fan_toric_variety(self, fm, check=check)
267
268
raise TypeError, "x must be a fan morphism or a list/tuple of polynomials"
269
270
271
def _an_element_(self):
272
"""
273
Construct a sample morphism.
274
275
OUTPUT:
276
277
An element of the homset.
278
279
EXAMPLES::
280
281
sage: P2 = toric_varieties.P2()
282
sage: homset = P2.Hom(P2)
283
sage: homset.an_element() # indirect doctest
284
Scheme endomorphism of 2-d CPR-Fano toric variety covered by 3 affine patches
285
Defn: Defined by sending Rational polyhedral fan in 2-d lattice N to
286
Rational polyhedral fan in 2-d lattice N.
287
"""
288
from sage.matrix.constructor import zero_matrix
289
zero = zero_matrix(self.domain().dimension_relative(),
290
self.codomain().dimension_relative())
291
return self(zero)
292
293
class SchemeHomset_points_toric_base(SchemeHomset_points):
294
"""
295
Base class for homsets with toric ambient spaces
296
297
INPUT:
298
299
- same as for :class:`SchemeHomset_points`.
300
301
OUPUT:
302
303
A scheme morphism of type
304
:class:`SchemeHomset_points_toric_base`.
305
306
EXAMPLES::
307
308
sage: P1xP1 = toric_varieties.P1xP1()
309
sage: P1xP1(QQ)
310
Set of rational points of 2-d CPR-Fano toric variety
311
covered by 4 affine patches
312
313
TESTS::
314
315
sage: import sage.schemes.toric.homset as HOM
316
sage: HOM.SchemeHomset_points_toric_base(Spec(QQ), P1xP1)
317
Set of rational points of 2-d CPR-Fano toric variety covered by 4 affine patches
318
"""
319
320
def is_finite(self):
321
"""
322
Return whether there are finitely many points.
323
324
OUTPUT:
325
326
Boolean.
327
328
EXAMPLES::
329
330
sage: P2 = toric_varieties.P2()
331
sage: P2.point_set().is_finite()
332
False
333
sage: P2.change_ring(GF(7)).point_set().is_finite()
334
True
335
"""
336
variety = self.codomain()
337
return variety.dimension() == 0 or variety.base_ring().is_finite()
338
339
def _naive_enumerator(self, ring=None):
340
"""
341
The naive enumerator over points of the toric variety.
342
343
INPUT:
344
345
- ``ring`` -- a ring (optional; defaults to the base ring of
346
the toric variety). The ring over which the points are
347
considered.
348
349
OUTPUT:
350
351
A :class:`sage.schemes.toric.points.NaiveFinitePointEnumerator`
352
instance that can be used to iterate over the points.
353
354
EXAMPLES::
355
356
sage: P123 = toric_varieties.P2_123(base_ring=GF(3))
357
sage: point_set = P123.point_set()
358
sage: iter(point_set._naive_enumerator()).next()
359
(0, 0, 1)
360
sage: iter(point_set).next()
361
[0 : 0 : 1]
362
"""
363
from sage.schemes.toric.points import \
364
NaiveFinitePointEnumerator, InfinitePointEnumerator
365
variety = self.codomain()
366
if ring is None:
367
ring = variety.base_ring()
368
if ring.is_finite():
369
return NaiveFinitePointEnumerator(variety.fan(), ring)
370
else:
371
return InfinitePointEnumerator(variety.fan(), ring)
372
373
374
class SchemeHomset_points_toric_field(SchemeHomset_points_toric_base):
375
"""
376
Set of rational points of a toric variety.
377
378
You should not use this class directly. Instead, use the
379
:meth:`~sage.schemes.generic.scheme.Scheme.point_set` method to
380
construct the point set of a toric variety.
381
382
INPUT:
383
384
- same as for :class:`~sage.schemes.generic.homset.SchemeHomset_points`.
385
386
OUPUT:
387
388
A scheme morphism of type
389
:class:`SchemeHomset_points_toric_field`.
390
391
EXAMPLES::
392
393
sage: P1xP1 = toric_varieties.P1xP1()
394
sage: P1xP1.point_set()
395
Set of rational points of 2-d CPR-Fano toric variety
396
covered by 4 affine patches
397
sage: P1xP1(QQ)
398
Set of rational points of 2-d CPR-Fano toric variety
399
covered by 4 affine patches
400
401
The quotient `\mathbb{P}^2 / \ZZ_3` over `GF(7)` by the diagonal
402
action. This is tricky because the base field has a 3-rd root of
403
unity::
404
405
sage: fan = NormalFan(ReflexivePolytope(2, 0))
406
sage: X = ToricVariety(fan, base_field=GF(7))
407
sage: point_set = X.point_set()
408
sage: point_set.cardinality()
409
21
410
sage: sorted(X.point_set().list())
411
[[0 : 0 : 1], [0 : 1 : 0], [0 : 1 : 1], [0 : 1 : 3],
412
[1 : 0 : 0], [1 : 0 : 1], [1 : 0 : 3], [1 : 1 : 0],
413
[1 : 1 : 1], [1 : 1 : 2], [1 : 1 : 3], [1 : 1 : 4],
414
[1 : 1 : 5], [1 : 1 : 6], [1 : 3 : 0], [1 : 3 : 1],
415
[1 : 3 : 2], [1 : 3 : 3], [1 : 3 : 4], [1 : 3 : 5],
416
[1 : 3 : 6]]
417
418
As for a non-compact example, the blow-up of the plane is the line
419
bundle $O_{\mathbf{P}^1}(-1)$. Its point set is the cartesian
420
product of the points on the base $\mathbf{P}^1$ with the points
421
on the fiber::
422
423
sage: fan = Fan([Cone([(1,0), (1,1)]), Cone([(1,1), (0,1)])])
424
sage: blowup_plane = ToricVariety(fan, base_ring=GF(3))
425
sage: point_set = blowup_plane.point_set()
426
sage: sorted(point_set.list())
427
[[0 : 1 : 0], [0 : 1 : 1], [0 : 1 : 2],
428
[1 : 0 : 0], [1 : 0 : 1], [1 : 0 : 2],
429
[1 : 1 : 0], [1 : 1 : 1], [1 : 1 : 2],
430
[1 : 2 : 0], [1 : 2 : 1], [1 : 2 : 2]]
431
432
Toric varieties with torus factors (that is, where the fan is not
433
full-dimensional) also work::
434
435
sage: F_times_Fstar = ToricVariety(Fan([Cone([(1,0)])]), base_field=GF(3))
436
sage: sorted(F_times_Fstar.point_set().list())
437
[[0 : 1], [0 : 2], [1 : 1], [1 : 2], [2 : 1], [2 : 2]]
438
439
TESTS::
440
441
sage: import sage.schemes.toric.homset as HOM
442
sage: HOM.SchemeHomset_points_toric_field(Spec(QQ), P1xP1)
443
Set of rational points of 2-d CPR-Fano toric variety covered by 4 affine patches
444
"""
445
446
def cardinality(self):
447
r"""
448
Return the number of points of the toric variety.
449
450
OUTPUT:
451
452
An integer or infinity. The cardinality of the set of points.
453
454
EXAMPLES::
455
456
sage: o = lattice_polytope.octahedron(3)
457
sage: V = ToricVariety(FaceFan(o))
458
sage: V.change_ring(GF(2)).point_set().cardinality()
459
27
460
sage: V.change_ring(GF(8, "a")).point_set().cardinality()
461
729
462
sage: V.change_ring(GF(101)).point_set().cardinality()
463
1061208
464
465
For non-smooth varieties over finite fields, the points are
466
actually constructed and iterated over. This works but is much
467
slower::
468
469
sage: fan = NormalFan(ReflexivePolytope(2, 0))
470
sage: X = ToricVariety(fan, base_field=GF(7))
471
sage: X.point_set().cardinality()
472
21
473
474
Fulton's formula does not apply since the variety is not
475
smooth. And, indeed, naive application gives a different
476
result::
477
478
sage: q = X.base_ring().order()
479
sage: n = X.dimension()
480
sage: d = map(len, fan().cones())
481
sage: sum(dk * (q-1)**(n-k) for k, dk in enumerate(d))
482
57
483
484
Over infinite fields the number of points is not very tricky::
485
486
sage: V.count_points()
487
+Infinity
488
489
ALGORITHM:
490
491
Uses the formula in Fulton [F]_, section 4.5.
492
493
REFERENCES:
494
495
.. [F]
496
Fulton, W., "Introduction to Toric Varieties",
497
Princeton University Press, 1993.
498
499
AUTHORS:
500
501
- Beth Malmskog (2013-07-14)
502
503
- Adriana Salerno (2013-07-14)
504
505
- Yiwei She (2013-07-14)
506
507
- Christelle Vincent (2013-07-14)
508
509
- Ursula Whitcher (2013-07-14)
510
"""
511
variety = self.codomain()
512
if not variety.base_ring().is_finite():
513
if variety.dimension_relative() == 0:
514
return ZZ.one()
515
else:
516
from sage.rings.infinity import Infinity
517
return Infinity
518
if not variety.is_smooth():
519
return super(SchemeHomset_points_toric_field, self).cardinality()
520
q = variety.base_ring().order()
521
n = variety.dimension()
522
d = map(len, variety.fan().cones())
523
return sum(dk * (q-1)**(n-k) for k, dk in enumerate(d))
524
525
def __iter__(self):
526
"""
527
Iterate over the points of the variety.
528
529
OUTPUT:
530
531
Iterator over points.
532
533
EXAMPLES::
534
535
sage: P123 = toric_varieties.P2_123(base_ring=GF(3))
536
sage: point_set = P123.point_set()
537
sage: iter(point_set.__iter__()).next()
538
[0 : 0 : 1]
539
sage: iter(point_set).next() # syntactic sugar
540
[0 : 0 : 1]
541
"""
542
for pt in self._naive_enumerator():
543
yield self(pt)
544
545
546
class SchemeHomset_points_subscheme_toric_field(SchemeHomset_points_toric_base):
547
548
def __iter__(self):
549
"""
550
Iterate over the points of the variety.
551
552
OUTPUT:
553
554
Iterator over points.
555
556
EXAMPLES::
557
558
sage: P2.<x,y,z> = toric_varieties.P2(base_ring=GF(5))
559
sage: cubic = P2.subscheme([x^3 + y^3 + z^3])
560
sage: list(cubic.point_set())
561
[[0 : 1 : 4], [1 : 0 : 4], [1 : 4 : 0], [1 : 1 : 2], [1 : 2 : 1], [1 : 3 : 3]]
562
sage: cubic.point_set().cardinality()
563
6
564
"""
565
ambient = super(
566
SchemeHomset_points_subscheme_toric_field, self
567
)._naive_enumerator()
568
X = self.codomain()
569
for p in ambient:
570
try:
571
X._check_satisfies_equations(p)
572
except TypeError:
573
continue
574
yield self(p)
575
576
577