1
+ r""""
2
+ Smooth Fano toric varieties.
1
3
2
- from sage .structure .sage_object import SageObject
3
-
4
- from sage .matrix .constructor import matrix
5
- from sage .matrix .special import identity_matrix
4
+ This module provides support for smooth Fano toric varieties, which has been classified by Batyrev in dimensions up to 4.
5
+ """
6
6
from sage .geometry .cone import Cone
7
7
from sage .geometry .fan import Fan , FaceFan
8
8
from sage .geometry .lattice_polytope import LatticePolytope
9
9
from sage .geometry .toric_lattice import ToricLattice
10
- from sage .rings .integer_ring import ZZ
11
10
from sage .rings .rational_field import QQ
12
11
from sage .arith .misc import GCD as gcd
13
12
from sage .schemes .toric .variety import (DEFAULT_PREFIX ,
14
13
ToricVariety_field ,
15
14
normalize_names )
15
+ from sage .schemes .toric .fano_variety import FanoToricVariety_field
16
16
17
17
from sage .categories .fields import Fields
18
18
_Fields = Fields ()
19
19
20
20
21
21
22
22
# TODO: add the method to fix a basis of the Picard group, and express divisors in this basis
23
- class SmoothFanoToricVariety_field (ToricVariety_field ):
23
+ class SmoothFanoToricVariety_field (FanoToricVariety_field ):
24
24
r"""
25
- Construct a Fano smooth toric variety from a reflexive polytope.
25
+ Construct a smooth Fano toric variety from a reflexive polytope.
26
26
27
27
INPUT:
28
28
- ``P`` -- reflexive polytope
@@ -45,190 +45,115 @@ class SmoothFanoToricVariety_field(ToricVariety_field):
45
45
OUTPUT: :class:`smooth Fano toric variety <SmoothFanoToricVariety_field>`
46
46
"""
47
47
48
- def __init__ (self , Delta_polar , fan , coordinate_points , point_to_ray ,
48
+ def __init__ (self , Delta_polar , fan ,
49
49
coordinate_names , coordinate_name_indices , base_field ):
50
50
r"""
51
51
See :class:`SmoothFanoToricVariety_field` for documentation.
52
52
53
53
Use ``SmoothFanoToricVariety`` to construct a smooth Fano toric variety.
54
-
55
- TESTS:
56
-
57
- sage:
58
54
"""
59
- self ._Delta_polar = Delta_polar
60
- self ._coordinate_points = tuple (coordinate_points )
61
- self ._point_to_ray = point_to_ray # AL: I may want to drop this later,
62
- if coordinate_name_indices is None :
63
- coordinate_name_indices = coordinate_points
64
- super ().__init__ (fan , coordinate_names ,
55
+ super ().__init__ (Delta_polar , fan , coordinate_names ,
65
56
coordinate_name_indices , base_field )
66
-
67
- # TODO: the _latex_ and _repr_ methods
68
57
69
-
70
- def change_ring (self , F ):
58
+ def _repr_ (self ):
71
59
r"""
72
- Return a smooth Fano toric variety over field ``F``, otherwise the same
73
- as ``self``.
74
-
75
- INPUT:
76
-
77
- - ``F`` -- field
78
-
79
- OUTPUT: :class:`smooth Fano toric variety <SmoothFanoToricVariety_field>` over ``F``
80
-
81
- .. NOTE::
82
-
83
- There is no need to have any relation between ``F`` and the base
84
- field of ``self``. If you do want to have such a relation, use
85
- :meth:`base_extend` instead.
60
+ Return a string representation of ``self``.
86
61
87
- EXAMPLES::
62
+ OUTPUT: string
88
63
89
- """
90
- if self .base_ring () == F :
91
- return self
92
- elif F not in _Fields :
93
- raise TypeError ("need a field to construct a Fano toric variety!"
94
- "\n Got %s" % F )
95
- else :
96
- return SmoothFanoToricVariety_field (self ._P , self ._fan ,
97
- self ._coordinate_points , self ._point_to_ray ,
98
- self .variable_names (), None , F )
99
- # coordinate_name_indices do not matter, we give explicit
100
- # names for all variables
101
-
102
- def coordinate_point_to_coordinate (self , point ):
103
- # TODO: if this is necessary
104
- pass
105
-
106
- def coordinate_points (self ):
107
- r"""
108
- Return indices of points of :meth:`Delta_polar` used for coordinates.
64
+ TESTS::
109
65
110
- OUTPUT: :class:`tuple` of integers
66
+ sage: P1xP1 = SmoothFanoToricVariety(
67
+ ....: Delta_polar=lattice_polytope.cross_polytope(2))
68
+ sage: print(P1xP1._repr_())
69
+ 2-d smooth Fano toric variety covered by 4 affine patches
111
70
"""
112
- return self ._coordinate_points
113
-
114
- def Delta (self ):
115
- r"""
116
- Return the reflexive polytope <sage.geometry.lattice_polytope.LatticePolytopeClass>`
117
- defining ``self``.
118
-
119
- OUTPUT:
120
-
121
- - reflexive :class:`lattice polytope`
71
+ return ("%d-d smooth Fano toric variety covered by %d affine patches"
72
+ % (self .dimension_relative (), self .fan ().ngenerating_cones ()))
122
73
123
- EXAMPLES::
124
-
125
- """
126
- return self ._Delta_polar .polar ()
127
-
128
- def Delta_polar (self ):
129
- r"""
130
- Return polar of :meth:`Delta`.
131
-
132
- OUTPUT:
133
-
134
- - reflexive :class:`lattice polytope`
135
-
136
- EXAMPLES::
137
-
138
- """
139
- return self ._Delta_polar
140
74
141
75
def SmoothFanoToricVariety (Delta = None ,
142
76
Delta_polar = None ,
143
- coordinate_points = None ,
144
- charts = None ,
145
77
coordinate_names = None ,
146
78
names = None ,
147
79
coordinate_name_indices = None ,
148
- make_simplicial = False ,
149
80
base_ring = None ,
150
81
base_field = None ,
151
82
check = True ):
152
83
r"""
153
- Construct a CPR-Fano toric variety.
84
+ Construct a smooth Fano toric variety.
85
+
86
+ INPUT:
87
+
88
+ - ``Delta`` -- reflexive :class:`lattice polytope
89
+ <sage.geometry.lattice_polytope.LatticePolytopeClass>`. The fan of the
90
+ constructed CPR-Fano toric variety will be a crepant subdivision of the
91
+ *normal fan* of ``Delta``. Either ``Delta`` or ``Delta_polar`` must be
92
+ given, but not both at the same time, since one is completely determined
93
+ by another via :meth:`polar
94
+ <sage.geometry.lattice_polytope.LatticePolytopeClass.polar>` method.
95
+
96
+ - ``Delta_polar`` -- reflexive :class:`lattice polytope
97
+ <sage.geometry.lattice_polytope.LatticePolytopeClass>`. The fan of the
98
+ constructed CPR-Fano toric variety will be a crepant subdivision of the
99
+ *face fan* of ``Delta_polar``. Either ``Delta`` or ``Delta_polar`` must
100
+ be given, but not both at the same time, since one is completely
101
+ determined by another via :meth:`polar
102
+ <sage.geometry.lattice_polytope.LatticePolytopeClass.polar>` method.
103
+
104
+ - ``coordinate_names`` -- names of variables for the coordinate ring, see
105
+ :func:`~sage.schemes.toric.variety.normalize_names`
106
+ for acceptable formats. If not given, indexed variable names will be
107
+ created automatically.
108
+
109
+ - ``names`` -- an alias of ``coordinate_names`` for internal
110
+ use. You may specify either ``names`` or ``coordinate_names``,
111
+ but not both.
112
+
113
+ - ``coordinate_name_indices`` -- list of integers, indices for indexed
114
+ variables. If not given, the index of each variable will coincide with
115
+ the index of the corresponding point of ``Delta_polar``.
116
+
117
+ - ``base_ring`` -- base field of the Fano toric variety
118
+ (default: `\QQ`)
119
+
120
+ - ``base_field`` -- alias for ``base_ring``. Takes precedence if
121
+ both are specified.
122
+
123
+ - ``check`` -- by default the input data will be checked for correctness
124
+ (e.g. that ``charts`` do form a subdivision of the normal fan of
125
+ ``Delta``). If you know for sure that the input is valid, you may
126
+ significantly decrease construction time using ``check=False`` option.
127
+
128
+ OUTPUT: :class:`smooth Fano toric variety <SmoothFanoToricVariety_field>`
154
129
"""
130
+ if names is not None :
131
+ if coordinate_names is not None :
132
+ raise ValueError ('You must not specify both coordinate_names and names!' )
133
+ coordinate_names = names
155
134
if (Delta is None ) == (Delta_polar is None ):
156
135
raise ValueError ("exactly one of Delta and Delta_polar must be given" )
157
136
if Delta_polar is None :
158
137
Delta_polar = Delta .polar ()
159
138
160
- # AL: maybe not checking reflexivity here, since we already have a database of smooth reflexive polytopes
161
- # unless the reflexivity check is not expensive here, we can add it for future more general use
162
- # if not Delta_polar.is_reflexive():
163
- # raise ValueError("Delta_polar must be reflexive")
164
-
165
- # Check/normalize coordinate_points and construct fan rays
166
- if coordinate_points is None :
167
- coordinate_points = list (range (Delta_polar .nvertices ()))
168
- if charts is not None :
169
- for chart in charts :
170
- for point in chart :
171
- if point not in coordinate_points :
172
- coordinate_points .append (point )
173
- elif coordinate_points == "vertices" :
174
- coordinate_points = list (range (Delta_polar .nvertices ()))
175
- elif coordinate_points == "all" :
176
- coordinate_points = list (range (Delta_polar .npoints ()))
177
- coordinate_points .remove (Delta_polar .origin ())
178
- elif coordinate_points == "all but facets" :
179
- coordinate_points = Delta_polar .skeleton_points (Delta_polar .dim () - 2 )
180
- elif isinstance (coordinate_points , str ):
181
- raise ValueError ("unrecognized description of the coordinate points!"
182
- "\n Got: %s" % coordinate_points )
183
- elif check :
184
- cp_set = set (coordinate_points )
185
- if len (cp_set ) != len (coordinate_points ):
186
- raise ValueError (
187
- "no repetitions are allowed for coordinate points!\n Got: %s"
188
- % coordinate_points )
189
- if not cp_set .issuperset (list (range (Delta_polar .nvertices ()))):
190
- raise ValueError ("all %d vertices of Delta_polar must be used "
191
- "for coordinates!\n Got: %s"
192
- % (Delta_polar .nvertices (), coordinate_points ))
193
- if Delta_polar .origin () in cp_set :
194
- raise ValueError ("the origin (point #%d) cannot be used for a "
195
- "coordinate!\n Got: %s"
196
- % (Delta_polar .origin (), coordinate_points ))
197
- point_to_ray = {point : n
198
- for n , point in enumerate (coordinate_points )}
139
+ if check and not Delta_polar .is_reflexive ():
140
+ raise ValueError ("Delta_polar must be reflexive" )
199
141
200
- # This can be simplified if LatticePolytopeClass is adjusted.
201
- rays = [Delta_polar .point (p ) for p in coordinate_points ]
202
- # Check/normalize charts and construct the fan based on them.
203
- if charts is None :
204
- # Start with the face fan
205
- fan = FaceFan (Delta_polar )
206
- else :
207
- # First of all, check that each chart is completely contained in a
208
- # single facet of Delta_polar, otherwise they do not form a
209
- # subdivision of the face fan of Delta_polar
210
- if check :
211
- facet_sets = [frozenset (facet .ambient_point_indices ())
212
- for facet in Delta_polar .facets ()]
213
- for chart in charts :
214
- is_bad = True
215
- for fset in facet_sets :
216
- if fset .issuperset (chart ):
217
- is_bad = False
218
- break
219
- if is_bad :
220
- raise ValueError (
221
- "%s does not form a chart of a subdivision of the "
222
- "face fan of %s!" % (chart , Delta_polar ))
223
- # AL: maybe skip this logic
224
- cones = [Cone ((rays [point_to_ray [point ]] for point in chart ),
225
- check = check )
226
- for chart in charts ]
227
- fan = Fan (cones , check = check )
228
- if check and not fan .is_complete ():
229
- raise ValueError ("given charts do not form a complete fan!" )
142
+ fan = FaceFan (Delta_polar )
143
+
144
+ if check and not fan .is_smooth ():
145
+ raise ValueError ("the face fan of Delta_polar is not smooth" )
146
+
147
+ # Check/normalize base_field
148
+ if base_field is not None :
149
+ base_ring = base_field
150
+ if base_ring is None :
151
+ base_ring = QQ
152
+ elif base_ring not in _Fields :
153
+ raise TypeError ("need a field to construct a Fano toric variety!"
154
+ "\n Got %s" % base_ring )
230
155
231
156
return SmoothFanoToricVariety_field (
232
- Delta_polar , fan , coordinate_points ,
233
- point_to_ray , coordinate_names , coordinate_name_indices , base_ring )
157
+ Delta_polar , fan , coordinate_names ,
158
+ coordinate_name_indices , base_ring )
234
159
0 commit comments