def P(self, n, names='z+', base_ring=QQ): r""" Construct the ``n``-dimensional projective space `\mathbb{P}^n`. INPUT: - ``n`` -- positive integer. The dimension of the projective space. - ``names`` -- string. Names for the homogeneous coordinates. See :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. OUTPUT: A :class:`CPR-Fano toric variety <sage.schemes.toric.fano_variety.CPRFanoToricVariety_field>`. EXAMPLES:: sage: P3 = toric_varieties.P(3) sage: P3 3-d CPR-Fano toric variety covered by 4 affine patches sage: P3.fan().rays() N( 1, 0, 0), N( 0, 1, 0), N( 0, 0, 1), N(-1, -1, -1) in 3-d lattice N sage: P3.gens() (z0, z1, z2, z3) """ # We are going to eventually switch off consistency checks, so we need # to be sure that the input is acceptable. try: n = ZZ(n) # make sure that we got a "mathematical" integer except TypeError: raise TypeError("dimension of the projective space must be a " "positive integer!\nGot: %s" % n) if n <= 0: raise ValueError("only projective spaces of positive dimension " "can be constructed!\nGot: %s" % n) m = identity_matrix(n).augment(matrix(n, 1, [-1] * n)) charts = [ list(range(i)) + list(range(i + 1, n + 1)) for i in range(n + 1) ] return CPRFanoToricVariety(Delta_polar=LatticePolytope( m.columns(), lattice=ToricLattice(n)), charts=charts, check=self._check, coordinate_names=names, base_ring=base_ring)
def torus(self, n, names='z+', base_ring=QQ): r""" Construct the ``n``-dimensional algebraic torus `(\mathbb{F}^\times)^n`. INPUT: - ``n`` -- non-negative integer. The dimension of the algebraic torus. - ``names`` -- string. Names for the homogeneous coordinates. See :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. OUTPUT: A :class:`toric variety <sage.schemes.toric.variety.ToricVariety_field>`. EXAMPLES:: sage: T3 = toric_varieties.torus(3); T3 3-d affine toric variety sage: T3.fan().rays() Empty collection in 3-d lattice N sage: T3.fan().virtual_rays() N(1, 0, 0), N(0, 1, 0), N(0, 0, 1) in 3-d lattice N sage: T3.gens() (z0, z1, z2) sage: sorted(T3.change_ring(GF(3)).point_set().list()) [[1 : 1 : 1], [1 : 1 : 2], [1 : 2 : 1], [1 : 2 : 2], [2 : 1 : 1], [2 : 1 : 2], [2 : 2 : 1], [2 : 2 : 2]] """ try: n = ZZ(n) except TypeError: raise TypeError('dimension of the torus must be an integer') if n < 0: raise ValueError('dimension must be non-negative') N = ToricLattice(n) fan = Fan([], lattice=N) return ToricVariety(fan, coordinate_names=names, base_field=base_ring)
def _make_CPRFanoToricVariety(self, name, coordinate_names, base_ring): r""" Construct a (crepant partially resolved) Fano toric variety and cache the result. INPUT: - ``name`` -- string. One of the pre-defined names in the ``toric_varieties_rays_cones`` data structure. - ``coordinate_names`` -- A string describing the names of the homogeneous coordinates of the toric variety. - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. OUTPUT: A :class:`CPR-Fano toric variety <sage.schemes.toric.fano_variety.CPRFanoToricVariety_field>`. EXAMPLES:: sage: toric_varieties.P2() # indirect doctest 2-d CPR-Fano toric variety covered by 3 affine patches """ rays, cones = toric_varieties_rays_cones[name] if coordinate_names is None: dict_key = (name, base_ring) else: coordinate_names = normalize_names(coordinate_names, len(rays), DEFAULT_PREFIX) dict_key = (name, base_ring) + tuple(coordinate_names) if dict_key not in self.__dict__: polytope = LatticePolytope(rays, lattice=ToricLattice(len(rays[0]))) points = [tuple(_) for _ in polytope.points()] ray2point = [points.index(r) for r in rays] charts = [[ray2point[i] for i in c] for c in cones] self.__dict__[dict_key] = \ CPRFanoToricVariety(Delta_polar=polytope, coordinate_points=ray2point, charts=charts, coordinate_names=coordinate_names, base_ring=base_ring, check=self._check) return self.__dict__[dict_key]
def WP(self, *q, **kw): # Specific keyword arguments instead of **kw would be preferable, # later versions of Python might support specific (optional) keyword # arguments after *q. r""" Construct weighted projective `n`-space over a field. INPUT: - ``q`` -- a sequence of positive integers relatively prime to one another. The weights ``q`` can be given either as a list or tuple, or as positional arguments. Two keyword arguments: - ``base_ring`` -- a field (default: `\QQ`). - ``names`` -- string or list (tuple) of strings (default 'z+'). See :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. OUTPUT: - A :class:`toric variety <sage.schemes.toric.variety.ToricVariety_field>`. If `q=(q_0,\dots,q_n)`, then the output is the weighted projective space `\mathbb{P}(q_0,\dots,q_n)` over ``base_ring``. ``names`` are the names of the generators of the homogeneous coordinate ring. EXAMPLES: A hyperelliptic curve `C` of genus 2 as a subscheme of the weighted projective plane `\mathbb{P}(1,3,1)`:: sage: X = toric_varieties.WP([1,3,1], names='x y z') sage: X.inject_variables() Defining x, y, z sage: g = y^2-(x^6-z^6) sage: C = X.subscheme([g]); C Closed subscheme of 2-d toric variety covered by 3 affine patches defined by: -x^6 + z^6 + y^2 """ if len(q) == 1: # tuples and lists of weights are acceptable input if isinstance(q[0], (list, tuple)): q = q[0] q = list(q) m = len(q) # allow case q=[1]? (not allowed presently) if m < 2: raise ValueError("more than one weight must be provided (got %s)" % q) for i in range(m): try: q[i] = ZZ(q[i]) except (TypeError): raise TypeError("the weights (=%s) must be integers" % q) if q[i] <= 0: raise ValueError( "the weights (=%s) must be positive integers" % q) if not gcd(q) == 1: raise ValueError("the weights (=%s) must be relatively prime" % q) # set default values for base_ring and names base_ring = QQ names = 'z+' for key in kw: if key == 'K': base_ring = kw['K'] elif key == 'base_ring': base_ring = kw['base_ring'] elif key == 'names': names = kw['names'] names = normalize_names(names, m, DEFAULT_PREFIX) else: raise TypeError("got an unexpected keyword argument %r" % key) L = ToricLattice(m) L_sub = L.submodule([L(q)]) Q = L / L_sub rays = [] cones = [] w = list(range(m)) L_basis = L.basis() for i in w: b = L_basis[i] v = Q.coordinate_vector(Q(b)) rays = rays + [v] w_c = w[:i] + w[i + 1:] cones = cones + [tuple(w_c)] fan = Fan(cones, rays) return ToricVariety(fan, coordinate_names=names, base_ring=base_ring)
def WP(self, *q, **kw): # Specific keyword arguments instead of **kw would be preferable, # later versions of Python might support specific (optional) keyword # arguments after *q. r""" Construct weighted projective `n`-space over a field. INPUT: - ``q`` -- a sequence of positive integers relatively prime to one another. The weights ``q`` can be given either as a list or tuple, or as positional arguments. Two keyword arguments: - ``base_ring`` -- a field (default: `\QQ`). - ``names`` -- string or list (tuple) of strings (default 'z+'). See :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. OUTPUT: - A :class:`toric variety <sage.schemes.toric.variety.ToricVariety_field>`. If `q=(q_0,\dots,q_n)`, then the output is the weighted projective space `\mathbb{P}(q_0,\dots,q_n)` over ``base_ring``. ``names`` are the names of the generators of the homogeneous coordinate ring. EXAMPLES: A hyperelliptic curve `C` of genus 2 as a subscheme of the weighted projective plane `\mathbb{P}(1,3,1)`:: sage: X = toric_varieties.WP([1,3,1], names='x y z') sage: X.inject_variables() Defining x, y, z sage: g = y^2-(x^6-z^6) sage: C = X.subscheme([g]); C Closed subscheme of 2-d toric variety covered by 3 affine patches defined by: -x^6 + z^6 + y^2 """ if len(q)==1: # tuples and lists of weights are acceptable input if isinstance(q[0], (list, tuple)): q = q[0] q = list(q) m = len(q) # allow case q=[1]? (not allowed presently) if m < 2: raise ValueError("more than one weight must be provided (got %s)" % q) for i in range(m): try: q[i] = ZZ(q[i]) except(TypeError): raise TypeError("the weights (=%s) must be integers" % q) if q[i] <= 0: raise ValueError("the weights (=%s) must be positive integers" % q) if not gcd(q) == 1: raise ValueError("the weights (=%s) must be relatively prime" % q) # set default values for base_ring and names base_ring = QQ names = 'z+' for key in kw: if key == 'K': base_ring = kw['K'] elif key == 'base_ring': base_ring = kw['base_ring'] elif key == 'names': names = kw['names'] names = normalize_names(names, m, DEFAULT_PREFIX) else: raise TypeError("got an unexpected keyword argument %r" % key) L = ToricLattice(m) L_sub = L.submodule([L(q)]) Q = L/L_sub rays = [] cones = [] w = range(m) L_basis = L.basis() for i in w: b = L_basis[i] v = Q.coordinate_vector(Q(b)) rays = rays + [v] w_c = w[:i] + w[i+1:] cones = cones + [tuple(w_c)] fan = Fan(cones,rays) return ToricVariety(fan, coordinate_names=names, base_ring=base_ring)