# Differences

This shows you the differences between two versions of the page.

— |
user_guide:tutorials:latest:apps_fulton [2020/01/22 09:02] (current) |
||
---|---|---|---|

Line 1: | Line 1: | ||

+ | ====== Toric polymake tutorial ====== | ||

+ | |||

+ | This tutorial will go over the basics of polymake and then focus on the ''application "fulton"'' for toric varieties. | ||

+ | |||

+ | ===== Quick start ===== | ||

+ | |||

+ | Below you see a small sample session. First switch to the application with the following command. | ||

+ | |||

+ | <code perl> | ||

+ | > application "fulton"; | ||

+ | </code> | ||

+ | Start by creating a cone. | ||

+ | |||

+ | <code perl> | ||

+ | > $c = new Cone(INPUT_RAYS=>[[-2,1],[1,1]]); | ||

+ | > print $c->HILBERT_BASIS; | ||

+ | </code> | ||

+ | You can ask for the binomials generating the associated toric ideal in two ways: The first gives a matrix of the binomial exponents, the second gives you the actual binomials. | ||

+ | |||

+ | <code perl> | ||

+ | > $toric = $c->TORIC_IDEAL; | ||

+ | > print $toric->BINOMIAL_GENERATORS, "\n"; | ||

+ | > print join("\n", @{$toric->GENERATORS}); | ||

+ | </code> | ||

+ | Asking for properties of the toric variety is done in the same manner as for polytopes. | ||

+ | |||

+ | <code perl> | ||

+ | > $tv = new NormalToricVariety($c); | ||

+ | > print "Is smooth? ", $tv->SMOOTH, "\n"; | ||

+ | > print "Is affine? ", $tv->AFFINE, "\n"; | ||

+ | > print "Is orbifold? ", $tv->ORBIFOLD, "\n"; | ||

+ | > print "Is complete? ", $tv->COMPLETE, "\n"; | ||

+ | > $tv->properties(); | ||

+ | </code> | ||

+ | ===== Affine toric varieties ===== | ||

+ | |||

+ | Affine toric varieties arise from cones. To dualize a (pointed) cone just construct a new cone switching facets and rays. | ||

+ | |||

+ | <code perl> | ||

+ | > $sigma = new Cone(INPUT_RAYS=>[[1,0,0],[0,1,0],[1,0,1],[0,1,1]]); | ||

+ | > $sigmad = polarize($sigma); | ||

+ | > print $sigmad->HILBERT_BASIS, "\n"; | ||

+ | > print $sigmad->TORIC_IDEAL->BINOMIAL_GENERATORS, "\n"; | ||

+ | > print $sigmad->TORIC_IDEAL->GENERATORS, "\n"; | ||

+ | </code> | ||

+ | The exponent vectors of the binomials generate the lattice of relations of the Hilbert basis of the dual cone. In particular we have | ||

+ | |||

+ | <code perl> | ||

+ | > $hb = $sigmad->HILBERT_BASIS; | ||

+ | > $binomials = $sigmad->TORIC_IDEAL->BINOMIAL_GENERATORS; | ||

+ | > print $binomials * $hb; | ||

+ | </code> | ||

+ | === Cyclic quotient singularities === | ||

+ | |||

+ | Two-dimensional pointed cones in two-dimensional space can always be generated by two rays in the standard form ''[[1,0],[-q,n]]'' with ''0<q<n'' and ''q'' and ''n'' coprime. | ||

+ | |||

+ | <code perl> | ||

+ | > $N7Q3 = new CyclicQuotient(N=>7, Q=>3); | ||

+ | > print primitive($N7Q3->RAYS); | ||

+ | </code> | ||

+ | CQS are deeply connected with the associated continued fractions. | ||

+ | |||

+ | <code perl> | ||

+ | > $cf = new Vector<Rational>($N7Q3->CONTINUED_FRACTION); | ||

+ | > print $cf, "\n"; | ||

+ | > print $cf->[0] -1/( $cf->[1] -1/ $cf->[2]), "\n"; | ||

+ | > $dcf = new Vector<Rational>($N7Q3->DUAL_CONTINUED_FRACTION); | ||

+ | > print $dcf, "\n"; | ||

+ | > print $dcf->[0] -1/ $dcf->[1], "\n"; | ||

+ | </code> | ||

+ | If we start with the Hilbert basis of the dual cone, sorted by first coordinate: | ||

+ | |||

+ | <code perl> | ||

+ | > print $N7Q3->WEIGHT_CONE->HILBERT_BASIS, "\n"; | ||

+ | > $sorted = new Matrix(sort(@{$N7Q3->WEIGHT_CONE->HILBERT_BASIS})); | ||

+ | > print $sorted; | ||

+ | </code> | ||

+ | Then the dual continued fraction expansion of ''n/(n-q)'' gives us relations among these elements: | ||

+ | |||

+ | <code perl> | ||

+ | > print $sorted->[0] + $sorted->[2] == $dcf->[0] * $sorted->[1],"\n"; | ||

+ | > print $sorted->[1] + $sorted->[3] == $dcf->[1] * $sorted->[2],"\n"; | ||

+ | </code> | ||

+ | Q: Derive and prove the general relation formula. | ||

+ | |||

+ | ==== Projective varieties ==== | ||

+ | |||

+ | Projective toric varieties arise from polytopes. Normal projective toric varieties arise from fans. To construct a projective toric variety, simply take the normal fan of a polytope and give it to the ''NormalToricVariety'' constructor. | ||

+ | |||

+ | <code perl> | ||

+ | > $PP2 = new NormalToricVariety(normal_fan(simplex(2))); | ||

+ | > print $PP2->RAYS; | ||

+ | > print $PP2->MAXIMAL_CONES; | ||

+ | > $PP2->VISUAL; | ||

+ | </code> | ||

+ | The Hasse diagram looks as follows: | ||

+ | |||

+ | <code perl> | ||

+ | > $PP2->HASSE_DIAGRAM->VISUAL; | ||

+ | </code> | ||

+ | Now consider the following two cones: | ||

+ | |||

+ | <code perl> | ||

+ | > $c1 = new Cone(simplex(2)); | ||

+ | > print $c1->HILBERT_BASIS, "\n"; | ||

+ | > $c2 = new Cone(simplex(2,2)); | ||

+ | > print $c2->HILBERT_BASIS, "\n"; | ||

+ | </code> | ||

+ | Lets look at the associated toric ideals: | ||

+ | |||

+ | <code perl> | ||

+ | > print "C1: ", join("\n", @{$c1->TORIC_IDEAL->GENERATORS}),"\n"; | ||

+ | > print "C2: ", join("\n", @{$c2->TORIC_IDEAL->GENERATORS}),"\n"; | ||

+ | </code> | ||

+ | The first ideal is actually ''0''. Both ideals are homogeneous and hence, they define projective varieties. | ||

+ | |||

+ | Q: What are these projective varieties? | ||

+ | |||

+ | === A non-projective toric variety === | ||

+ | |||

+ | Not every fan is the normal fan of a polytope. Here we give an example. | ||

+ | |||

+ | <code perl> | ||

+ | > $f = new PolyhedralFan(INPUT_RAYS=> | ||

+ | > [[1,0,0],[0,1,0],[-1,-1,-1], | ||

+ | > [0,0,1],[2,1,1],[1,2,1],[1,1,2]], | ||

+ | > INPUT_CONES=>[[0,1,2],[0,2,3], | ||

+ | > [1,2,3],[4,5,6],[0,1,4],[1,3,5], | ||

+ | > [0,3,6],[1,4,5],[3,5,6],[0,4,6]] | ||

+ | > ); | ||

+ | > $tv = new NormalToricVariety($f); | ||

+ | > print "Projective? ", $tv->PROJECTIVE, "\n"; | ||

+ | > print "Smooth? ", $tv->SMOOTH, "\n"; | ||

+ | > print "Complete? ", $tv->COMPLETE, "\n"; | ||

+ | > $tv->VISUAL; | ||

+ | </code> | ||

+ | === Hirzebruch surfaces === | ||

+ | |||

+ | Hirzebruch surfaces come from two-dimensional complete fans with exactly four rays. Smoothness makes it possible to bring these fans into a standard form such that we arrive at a one-parameter family. | ||

+ | |||

+ | <code perl> | ||

+ | > $h1 = hirzebruch_surface(1); | ||

+ | > print $h1->RAYS; | ||

+ | > $h1->VISUAL; | ||

+ | > $h2 = hirzebruch_surface(2); | ||

+ | > print $h2->RAYS; | ||

+ | > $h2->VISUAL; | ||

+ | </code> | ||

+ | Q: Construct the/an associated polytope. | ||

+ | |||

+ | Q: Prove the standard form for complete smooth fans in two dimensions with exactly four rays. | ||

+ | |||

+ | polymake has a method to reconstruct a polytope from a regular fan / projective toric variety. | ||

+ | |||

+ | <code perl> | ||

+ | > $A = generating_polyhedron_facets($h2); | ||

+ | > print $A; | ||

+ | </code> | ||

+ | This polytope has the given fan as a normal fan. | ||

+ | |||

+ | <code perl> | ||

+ | > $P = new Polytope(INEQUALITIES=>$A); | ||

+ | > $FF = normal_fan($P); | ||

+ | > print $FF->RAYS; | ||

+ | > print $FF->MAXIMAL_CONES; | ||

+ | </code> | ||

+ | The polytope we just constructed looks like: | ||

+ | |||

+ | <code perl> | ||

+ | > $P->VISUAL; | ||

+ | </code> | ||

+ | The polytope is not unique. Any polytope with the same facet vectors and combinatorics will have the same normal fan. | ||

+ | |||

+ | Its normal fan is exactly the fan we started with. | ||

+ | |||

+ | <code perl> | ||

+ | > $FF->VISUAL; | ||

+ | </code> | ||

+ | === Simple, not smooth === | ||

+ | |||

+ | <code perl> | ||

+ | > $p = new Polytope(POINTS=>[ | ||

+ | > [1, 0, 0, 0], | ||

+ | > [1, 1, 1, 0], | ||

+ | > [1, 1, 0, 1], | ||

+ | > [1, 0, 1, 1]]); | ||

+ | > print "Simple? ", $p->SIMPLE, "\n"; | ||

+ | > print "Smooth? ", $p->SMOOTH, "\n"; | ||

+ | </code> | ||

+ | ==== Non-normal toric varieties ==== | ||

+ | |||

+ | polymake only handles normal toric varieties. Nevertheless we can use it to get at the toric ideal of a non-normal toric variety by giving the semigroup generators directly as a mock Hilbert basis. For example for the Neil parabola use: | ||

+ | |||

+ | <code perl> | ||

+ | > $c = new Cone(HILBERT_BASIS_GENERATORS=>[[[2],[3]],[[]]]); | ||

+ | > print $c->TORIC_IDEAL->BINOMIAL_GENERATORS; | ||

+ | > print $c->TORIC_IDEAL->GENERATORS; | ||

+ | </code> | ||

+ | If we build a new cone from this semigroup, we see that it was not saturated. The semigroup generated by 2 and 3 does not come from a cone. | ||

+ | |||

+ | <code perl> | ||

+ | > $cc = new Cone(INPUT_RAYS=>$c->HILBERT_BASIS_GENERATORS->[0]); | ||

+ | > print $cc->RAYS, "\n"; | ||

+ | > print $cc->HILBERT_BASIS, "\n"; | ||

+ | </code> | ||

+ | Q: What are necessary conditions for a semigroup to come from a cone? | ||

+ | |||

+ | === Smooth vs normal === | ||

+ | |||

+ | It is an open question by Oda whether smoothness and normality of polytopes are equivalent. | ||

+ | |||

+ | <code perl> | ||

+ | > print $p->VERTICES, "\n"; | ||

+ | > print "Normal? ", $p->NORMAL, "\n"; | ||

+ | > print "Smooth? ", $p->SMOOTH, "\n"; | ||

+ | > help "NORMAL"; | ||

+ | > help "SMOOTH"; | ||

+ | > print $p->HILBERT_BASIS; | ||

+ | </code> | ||

+ | ===== Dealing with torus invariant divisors ===== | ||

+ | |||

+ | The application ''fulton'' allows one to compute several properties of divisors and even divisor classes. First build a divisor from its representation as a sum of primitive divisors. | ||

+ | |||

+ | <code perl> | ||

+ | > $tv = hirzebruch_surface(4); | ||

+ | > $d = $tv->DIVISOR(COEFFICIENTS=>[1,1,1,1]); | ||

+ | </code> | ||

+ | Then treat them like any polymake object. | ||

+ | |||

+ | <code perl> | ||

+ | > print "Effective? ", $d->EFFECTIVE, "\n"; | ||

+ | > print "Ample? ", $d->AMPLE, "\n"; | ||

+ | > print "Basepoint free? ", $d->BASEPOINT_FREE, "\n"; | ||

+ | > print "Nef? ", $d->NEF, "\n"; | ||

+ | > print "Cartier? ", $d->CARTIER, "\n"; | ||

+ | </code> | ||

+ | The following code produces the vertices of the polytope of global sections. | ||

+ | |||

+ | <code perl> | ||

+ | > $pd = $d->SECTION_POLYTOPE; | ||

+ | > print $pd->VERTICES; | ||

+ | </code> | ||

+ | Furthermore one can deal with rational divisor classes, rather than divisors, using the class group exact sequence. Its projection matrix can be produced as follows. | ||

+ | |||

+ | <code perl> | ||

+ | > print $tv->RATIONAL_DIVISOR_CLASS_GROUP->PROJECTION; | ||

+ | </code> | ||

+ | Then one can access the nef cone, effective cone and Mori cone of the toric variety: | ||

+ | |||

+ | <code perl> | ||

+ | > print "Nef cone:\n", $tv->NEF_CONE->RAYS,"\n"; | ||

+ | > print "Effective cone:\n", $tv->EFFECTIVE_CONE->RAYS,"\n"; | ||

+ | > print "Mori cone:\n", $tv->MORI_CONE->RAYS,"\n"; | ||

+ | </code> | ||

+ | ===== Accessing Singular ===== | ||

+ | |||

+ | [[https://www.singular.uni-kl.de/|Singular]] is a computer algebra system developed in Kaiserslautern. It can be accessed from polymake on different levels. For ideals there are low-level c++ methods providing basic funtionality to compute Groebner bases, radicals, etc. At top level for users there are perl methods giving the opportunity to send command strings to Singular if something has not been accessed on c++ level yet. This allows fast proof of concept implementations. | ||

+ | |||

+ | <code perl> | ||

+ | > application "fulton"; | ||

+ | > $c = new Cone(INPUT_RAYS=>[[-1,1],[0,1],[1,1]]); | ||

+ | > $tv = new NormalToricVariety($c); | ||

+ | > $toric = $c->TORIC_IDEAL; | ||

+ | > singular_eval("listvar();"); | ||

+ | > $radical = $toric->RADICAL; | ||

+ | > print join("\n", @{$radical->GENERATORS}); | ||

+ | > singular_eval("listvar();"); | ||

+ | > $ideal = $tv->WEIGHT_CONE->TORIC_IDEAL; | ||

+ | > print $ideal; | ||

+ | </code> | ||

+ | It is possible to execute arbitrary Singular commands from polymake using the ''singular_eval'' command. First build your command as a string. | ||

+ | |||

+ | <code perl> | ||

+ | > $cmd = "ring r = 0,(x_0,x_1,x_2),dp;"; | ||

+ | > print $cmd; | ||

+ | </code> | ||

+ | Then hand this string to ''singular_eval''. | ||

+ | |||

+ | <code perl> | ||

+ | > singular_eval($cmd); | ||

+ | > singular_eval("r;"); | ||

+ | </code> | ||

+ | One can also retrieve variables from Singular to polymake using the ''singular_get_var'' command in the following manner. | ||

+ | |||

+ | <code perl> | ||

+ | > singular_eval("int n = nvars(r);"); | ||

+ | > $n = singular_get_var("n"); | ||

+ | > print $n,"\n"; | ||

+ | </code> | ||

+ | It is possible to retrieve the following datatypes from Singular: ''int'', ''intmat'', ''intvec'' and ''poly''. | ||

+ | |||

+ | <code perl> | ||

+ | > singular_eval("poly p = x_2^2-x_0*x_1"); | ||

+ | > $p = singular_get_var("p"); | ||

+ | > print $p,"\n"; | ||

+ | </code> | ||

+ | To load a Singular library, you can use the ''load_singular_library'' command with the library name. Afterwards all library methods are accessible, as in the following example. | ||

+ | |||

+ | <code perl> | ||

+ | > load_singular_library("deform.lib"); | ||

+ | > singular_eval("ideal i = x_0*x_1, x_2;"); | ||

+ | > singular_eval("def L = versal(i);"); | ||

+ | > singular_eval("L;"); | ||

+ | </code> | ||