source: git/Singular/LIB/oldpolymake.lib @ 48935b4

spielwiese
Last change on this file since 48935b4 was 48935b4, checked in by Martin Lee <martinlee84@…>, 11 years ago
fix: loading of polymake.so in oldpolymake.lib
  • Property mode set to 100644
File size: 82.4 KB
Line 
1version="version oldpolymake.lib 4.0.0.0 Jun_2013 ";
2category="Tropical Geometry";
3info="
4LIBRARY:   oldpolymake.lib    Computations with polytopes and fans,
5                              interface to polymake and TOPCOM
6AUTHOR:    Thomas Markwig,  email: keilen@mathematik.uni-kl.de
7
8WARNING:
9   Most procedures will not work unless polymake or topcom is installed and
10   if so, they will only work with the operating system LINUX!
11   For more detailed information see IMPORTANT NOTE respectively consult the
12   help string of the procedures.
13
14   The conventions used in this library for polytopes and fans, e.g. the
15   length and labeling of their vertices resp. rays, differs from the conventions
16   used in polymake and thus from the conventions used in the polymake
17   extension polymake.so of Singular. We recommend to use the newer polymake.so
18   whenever possible.
19
20IMPORTANT NOTE:
21   Even though this is a Singular library for computing polytopes and fans
22   such as the Newton polytope or the Groebner fan of a polynomial, most of
23   the hard computations are NOT done by Singular but by the program
24@* - polymake by Ewgenij Gawrilow, TU Berlin and Michael Joswig, TU Darmstadt
25@*   (see http://www.math.tu-berlin.de/polymake/), 
26@* respectively (only in the procedure triangulations) by the program
27@* - topcom by Joerg Rambau, Universitaet Bayreuth (see
28@*   http://www.uni-bayreuth.de/departments/wirtschaftsmathematik/rambau/TOPCOM);
29@*   this library should rather be seen as an interface which allows to use a
30     (very limited) number of options which polymake respectively topcom offers
31     to compute with polytopes and fans and to make the results available in
32     Singular for further computations;
33     moreover, the user familiar with Singular does not have to learn the syntax
34     of polymake or topcom, if the options offered here are sufficient for his
35     purposes.
36@*   Note, though, that the procedures concerned with planar polygons are
37     independent of both, polymake and topcom.
38
39PROCEDURES USING POLYMAKE:
40  polymakePolytope()  computes the vertices of a polytope using polymake
41  newtonPolytope()    computes the Newton polytope of a polynomial
42  newtonPolytopeLP()  computes the lattice points of the Newton polytope
43  normalFan()         computes the normal fan of a polytope
44  groebnerFan()       computes the Groebner fan of a polynomial
45
46PROCEDURES USING TOPCOM:
47  triangulations()    computes all triangulations of a marked polytope
48  secondaryPolytope() computes the secondary polytope of a marked polytope
49
50PROCEDURES USING POLYMAKE AND TOPCOM:
51  secondaryFan()      computes the secondary fan of a marked polytope
52
53PROCEDURES CONERNED WITH PLANAR POLYGONS:
54  cycleLength()    computes the cycleLength of cycle
55  splitPolygon()   splits a marked polygon into vertices, facets, interior points
56  eta()            computes the eta-vector of a triangulation
57  findOrientedBoundary()  computes the boundary of a convex hull
58  cyclePoints()    computes lattice points connected to some lattice point
59  latticeArea()    computes the lattice area of a polygon
60  picksFormula()   computes the ingrediants of Pick's formula for a polygon
61  ellipticNF()     computes the normal form of an elliptic polygon
62  ellipticNFDB()   displays the 16 normal forms of elliptic polygons
63
64KEYWORDS:    polytope; fan; secondary fan; secondary polytope; polymake;
65             Newton polytope; Groebner fan
66";
67
68////////////////////////////////////////////////////////////////////////////////
69/// Auxilary Static Procedures in this Library
70////////////////////////////////////////////////////////////////////////////////
71/// - scalarproduct
72/// - intmatcoldelete
73/// - intmatconcat
74/// - sortlist
75/// - minInList
76/// - stringdelete
77/// - abs
78/// - commondenominator
79/// - maxPosInIntvec
80/// - maxPosInIntmat
81/// - sortintvec
82/// - matrixtointmat
83////////////////////////////////////////////////////////////////////////////////
84
85////////////////////////////////////////////////////////////////////////////////
86LIB "poly.lib";
87LIB "linalg.lib";
88LIB "random.lib";
89////////////////////////////////////////////////////////////////////////////////
90
91static proc mod_init ()
92{
93  LIB "gfanlib.so";
94  LIB "polymake.so";
95}
96
97/////////////////////////////////////////////////////////////////////////////
98/// PROCEDURES USING POLYMAKE
99/////////////////////////////////////////////////////////////////////////////
100
101proc polymakePolytope (intmat points)
102"USAGE:  polymakePolytope(points);   polytope intmat
103ASSUME:  each row of points gives the coordinates of a lattice point of a
104         polytope with their affine coordinates as given by the output of
105         secondaryPolytope
106PURPOSE: the procedure calls polymake to compute the vertices of the polytope
107         as well as its dimension and information on its facets
108RETURN:  list, L with four entries
109@*            L[1] : an integer matrix whose rows are the coordinates of vertices
110                     of the polytope
111@*            L[2] : the dimension of the polytope
112@*            L[3] : a list whose ith entry explains to which vertices the
113                     ith vertex of the Newton polytope is connected
114                     -- i.e. L[3][i] is an integer vector and an entry k in
115                        there means that the vertex L[1][i] is connected to the
116                        vertex L[1][k]
117@*            L[4] : an matrix of type bigintmat whose rows mulitplied by
118                     (1,var(1),...,var(nvar)) give a linear system of equations
119                     describing the affine hull of the polytope,
120                     i.e. the smallest affine space containing the polytope
121NOTE: -  for its computations the procedure calls the program polymake by
122         Ewgenij Gawrilow, TU Berlin and Michael Joswig, TU Darmstadt;
123         it therefore is necessary that this program is installed in order
124         to use this procedure;
125         see http://www.math.tu-berlin.de/polymake/
126@*    -  note that in the vertex edge graph we have changed the polymake
127         convention which starts indexing its vertices by zero while we start
128         with one !
129EXAMPLE: example polymakePolytope;   shows an example"
130{
131  // add a first column to polytope as homogenising coordinate
132  points=intmatAddFirstColumn(points,"points");
133  polytope polytop=polytopeViaPoints(points);
134  list graph=vertexAdjacencyGraph(polytop)[2];
135  int i,j;
136  for (i=1;i<=size(graph);i++)
137  {
138    for (j=1;j<=size(graph[i]);j++)
139    {
140      graph[i][j]=graph[i][j]+1;
141    }
142  }
143  return(list(intmatcoldelete(vertices(polytop),1),dimension(polytop),graph,equations(polytop)));
144}
145example
146{
147   "EXAMPLE:";
148   echo=2;
149   // the lattice points of the unit square in the plane
150   list points=intvec(0,0),intvec(0,1),intvec(1,0),intvec(1,1);
151   // the secondary polytope of this lattice point configuration is computed
152   intmat secpoly=secondaryPolytope(points)[1];
153   list np=polymakePolytope(secpoly);
154   // the vertices of the secondary polytope are:
155   np[1];
156   // its dimension is
157   np[2];
158   // np[3] contains information how the vertices are connected to each other,
159   // e.g. the first vertex (number 0) is connected to the second one
160   np[3][1];
161   // the affine hull has the equation
162   ring r=0,x(1..4),dp;
163   matrix M[5][1]=1,x(1),x(2),x(3),x(4);
164   intmat(np[4])*M;
165}
166
167/////////////////////////////////////////////////////////////////////////////
168
169proc newtonPolytope (poly f)
170"USAGE: newtonPolytope(f);  f poly
171RETURN: list, L with four entries
172@*            L[1] : an integer matrix whose rows are the coordinates of vertices
173                     of the Newton polytope of f
174@*            L[2] : the dimension of the Newton polytope of f
175@*            L[3] : a list whose ith entry explains to which vertices the
176                     ith vertex of the Newton polytope is connected
177                     -- i.e. L[3][i] is an integer vector and an entry k in
178                        there means that the vertex L[1][i] is
179                        connected to the vertex L[1][k]
180@*            L[4] : an matrix of type bigintmat whose rows mulitplied by
181                     (1,var(1),...,var(nvar)) give a linear system of equations
182                     describing the affine hull of the Newton polytope, i.e. the
183                     smallest affine space containing the Newton polytope
184NOTE: -  if we replace the first column of L[4] by zeros, i.e. if we move
185         the affine hull to the origin, then we get the equations for the
186         orthogonal complement of the linearity space of the normal fan dual
187         to the Newton polytope, i.e. we get the EQUATIONS that
188         we need as input for polymake when computing the normal fan
189@*    -  the procedure calls for its computation polymake by Ewgenij Gawrilow,
190         TU Berlin and Michael Joswig, so it only works if polymake is installed;
191         see http://www.math.tu-berlin.de/polymake/
192EXAMPLE: example newtonPolytope;   shows an example"
193{
194  int i,j;
195  // compute the list of exponent vectors of the polynomial,
196  // which are the lattice points
197  // whose convex hull is the Newton polytope of f
198  intmat exponents[size(f)][nvars(basering)];
199  while (f!=0)
200  {
201    i++;
202    exponents[i,1..nvars(basering)]=leadexp(f);
203    f=f-lead(f);
204  }
205  // call polymakePolytope with exponents
206  return(polymakePolytope(exponents));
207}
208example
209{
210   "EXAMPLE:";
211   echo=2;
212   ring r=0,(x,y,z),dp;
213   matrix M[4][1]=1,x,y,z;
214   poly f=y3+x2+xy+2xz+yz+z2+1;
215   // the Newton polytope of f is
216   list np=newtonPolytope(f);
217   // the vertices of the Newton polytope are:
218   np[1];
219   // its dimension is
220   np[2];
221   // np[3] contains information how the vertices are connected to each other,
222   // e.g. the first vertex (number 0) is connected to the second, third and
223   //      fourth vertex
224   np[3][1];
225   //////////////////////////
226   f=x2-y3;
227   // the Newton polytope of f is
228   np=newtonPolytope(f);
229   // the vertices of the Newton polytope are:
230   np[1];
231   // its dimension is
232   np[2];   
233   // the Newton polytope is contained in the affine space given
234   //     by the equations
235   intmat(np[4])*M;
236}
237
238/////////////////////////////////////////////////////////////////////////////
239
240proc newtonPolytopeLP (poly f)
241"USAGE:  newtonPolytopeLP(f);  f poly
242RETURN: list, the exponent vectors of the monomials occuring in f,
243              i.e. the lattice points of the Newton polytope of f
244EXAMPLE: example normalFan;   shows an example"
245{
246  list np;
247  int i=1;
248  while (f!=0)
249  {
250    np[i]=leadexp(f);
251    f=f-lead(f);
252    i++;
253  }
254  return(np);
255}
256example
257{
258   "EXAMPLE:";
259   echo=2;
260   ring r=0,(x,y,z),dp;
261   poly f=y3+x2+xy+2xz+yz+z2+1;
262   // the lattice points of the Newton polytope of f are
263   newtonPolytopeLP(f);
264}
265
266/////////////////////////////////////////////////////////////////////////////
267
268proc normalFan (intmat vertices,intmat affinehull,list graph,int er,list #)
269"USAGE:  normalFan (vert,aff,graph,rays,[,#]);   vert,aff intmat,  graph list, rays int, # string
270ASSUME:  - vert is an integer matrix whose rows are the coordinate of
271           the vertices of a convex lattice polytope;
272@*       - aff describes the affine hull of this polytope, i.e.
273           the smallest affine space containing it, in the following sense:
274           denote by n the number of columns of vert, then multiply aff by
275           (1,x(1),...,x(n)) and set the resulting terms to zero in order to
276           get the equations for the affine hull;
277@*       - the ith entry of graph is an integer vector describing to which
278           vertices the ith vertex is connected, i.e. a k as entry means that
279           the vertex vert[i] is connected to vert[k];
280@*       - the integer rays is either one (if the extreme rays should be
281           computed) or zero (otherwise)
282RETURN:  list, the ith entry of L[1] contains information about the cone in the
283               normal fan dual to the ith vertex of the polytope
284@*             L[1][i][1] = integer matrix representing the inequalities which
285                            describe the cone dual to the ith vertex
286@*             L[1][i][2] = a list which contains the inequalities represented
287                            by L[i][1] as a list of strings, where we use the
288                            variables x(1),...,x(n)
289@*             L[1][i][3] = only present if 'er' is set to 1; in that case it is
290                            an interger matrix whose rows are the extreme rays
291                            of the cone
292@*             L[2] = is an integer matrix whose rows span the linearity space
293                      of the fan, i.e. the linear space which is contained in
294                      each cone
295NOTE:    - the procedure calls for its computation polymake by Ewgenij Gawrilow,
296           TU Berlin and Michael Joswig, so it only works if polymake is
297           installed;
298           see http://www.math.tu-berlin.de/polymake/
299@*       - in the optional argument # it is possible to hand over other names
300           for the variables to be used -- be careful, the format must be correct
301           and that is not tested, e.g. if you want the variable names to be
302           u00,u10,u01,u11 then you must hand over the string u11,u10,u01,u11
303EXAMPLE: example normalFan;   shows an example"
304{
305  list ineq; // stores the inequalities of the cones
306  int i,j,k;
307  // we work over the following ring 
308  execute("ring ineqring=0,x(1.."+string(ncols(vertices))+"),lp;");
309  string greatersign=">";
310  // create the variable names
311  if (size(#)>0)
312  {
313    if (typeof(#[1])=="string")
314    {
315      kill ineqring;
316      execute("ring ineqring=0,("+#[1]+"),lp;");
317    }
318    if (size(#)>1)
319    {
320      greatersign="<";
321    }
322  }
323  //////////////////////////////////////////////////////////////////
324  // Compute first the inequalities of the cones
325  //////////////////////////////////////////////////////////////////
326  matrix VAR[1][ncols(vertices)]=maxideal(1);
327  matrix EXP[ncols(vertices)][1];
328  poly p,pl,pr;
329  // consider all vertices of the polytope
330  for (i=1;i<=nrows(vertices);i++)
331  {
332    // first we produce for each vertex in the polytope
333    // the inequalities describing the dual cone in the normal fan
334    list pp;  // contain strings representing the inequalities
335              // describing the normal cone
336    intmat ie[size(graph[i])][ncols(vertices)]; // contains the inequalities
337                                                // as rows
338    // consider all the vertices to which the ith vertex in the
339    // polytope is connected by an edge
340    for (j=1;j<=size(graph[i]);j++)
341    {
342      // produce the vector ie_j pointing from the jth vertex to the ith vertex;
343      // this will be the jth inequality for the cone in the normal fan dual to
344      // the ith vertex
345      ie[j,1..ncols(vertices)]=vertices[i,1..ncols(vertices)]-vertices[graph[i][j],1..ncols(vertices)];
346      EXP=ie[j,1..ncols(vertices)];
347      // build a linear polynomial with the entries of ie_j as coefficients
348      p=(VAR*EXP)[1,1];
349      pl,pr=0,0;
350      // separate the terms with positive coefficients in p from
351      // those with negative coefficients
352      for (k=1;k<=size(p);k++)
353      {
354        if (leadcoef(p[k])<0)
355        {
356          pr=pr-p[k];
357        }
358        else
359        {
360          pl=pl+p[k];
361        }
362      }
363      // build the string which represents the jth inequality
364      // for the cone dual to the ith vertex
365      // as polynomial inequality of type string, and store this
366      // in the list pp as jth entry
367      pp[j]=string(pl)+" "+greatersign+" "+string(pr);
368    }
369    // all inequalities for the ith vertex are stored in the list ineq
370    ineq[i]=list(ie,pp);
371    kill ie,pp; // kill certain lists
372  }
373  // remove the first column of affine hull to compute the linearity space
374  intmat linearity[1][ncols(vertices)];
375  if (nrows(affinehull)>0)
376  {
377    linearity=intmatcoldelete(affinehull,1);
378  }
379  //////////////////////////////////////////////////////////////////
380  // Compute next the extreme rays of the cones
381  //////////////////////////////////////////////////////////////////
382  if (er==1)
383  {
384    list extremerays; // keeps the result
385    cone kegel;
386    intmat linearspan=intmatAddFirstColumn(linearity,"rays");
387    intmat M; // the matrix keeping the inequalities
388    for (i=1;i<=size(ineq);i++)
389    {
390      kegel=coneViaInequalities(intmatAddFirstColumn(ineq[i][1],"rays"),linearspan);
391      extremerays[i]=intmatcoldelete(rays(kegel),1);
392    }
393    for (i=1;i<=size(ineq);i++)
394    {
395      ineq[i]=ineq[i]+list(extremerays[i]);
396    }
397  }
398  // get the linearity space
399  return(list(ineq,linearity));
400}
401example
402{
403   "EXAMPLE:";
404   echo=2;
405   ring r=0,(x,y,z),dp;
406   matrix M[4][1]=1,x,y,z;
407   poly f=y3+x2+xy+2xz+yz+z2+1;
408   // the Newton polytope of f is
409   list np=newtonPolytope(f);
410   // the Groebner fan of f, i.e. the normal fan of the Newton polytope
411   list gf=normalFan(np[1],np[4],np[3],1,"x,y,z");
412   // the number of cones in the Groebner fan of f is:
413   size(gf[1]);
414   // the inequalities of the first cone as matrix are:
415   print(gf[1][1][1]);
416   // the inequalities of the first cone as string are:
417   print(gf[1][1][2]);
418   // the rows of the following matrix are the extreme rays of the first cone:
419   print(gf[1][1][3]);
420   // each cone contains the linearity space spanned by:
421   print(gf[2]);
422}
423
424/////////////////////////////////////////////////////////////////////////////
425
426proc groebnerFan (poly f)
427"USAGE:  groebnerFan(f);  f poly
428RETURN:  list, the ith entry of L[1] contains information about the ith cone
429               in the Groebner fan dual to the ith vertex in the Newton
430               polytope of the f
431@*             L[1][i][1] = integer matrix representing the inequalities
432                            which describe the cone         
433@*             L[1][i][2] = a list which contains the inequalities represented
434                            by L[1][i][1] as a list of strings
435@*             L[1][i][3] = an interger matrix whose rows are the extreme rays
436                            of the cone
437@*             L[2] = is an integer matrix whose rows span the linearity space
438                      of the fan, i.e. the linear space which is contained
439                      in each cone               
440@*             L[3] = the Newton polytope of f in the format of the procedure
441                      newtonPolytope
442@*             L[4] = integer matrix where each row represents the exponent
443                      vector of one monomial occuring in the input polynomial
444NOTE: - if you have already computed the Newton polytope of f then you might want
445        to use the procedure normalFan instead in order to avoid doing costly
446        computation twice
447@*    - the procedure calls for its computation polymake by Ewgenij Gawrilow,
448        TU Berlin and Michael Joswig, so it only works if polymake is installed;
449        see http://www.math.tu-berlin.de/polymake/
450EXAMPLE: example groebnerFan;   shows an example"
451{
452  int i,j;
453  // compute the list of exponent vectors of the polynomial, which are
454  // the lattice points whose convex hull is the Newton polytope of f
455  intmat exponents[size(f)][nvars(basering)];
456  while (f!=0)
457  {
458    i++;
459    exponents[i,1..nvars(basering)]=leadexp(f);
460    f=f-lead(f);
461  }
462  // call polymakePolytope with exponents
463  list newtonp=polymakePolytope(exponents);
464  // get the variables as string
465  string variablen;
466  for (i=1;i<=nvars(basering);i++)
467  {
468    variablen=variablen+string(var(i))+",";
469  }
470  variablen=variablen[1,size(variablen)-1];
471  // call normalFan in order to compute the Groebner fan
472  list gf=normalFan(newtonp[1],newtonp[4],newtonp[3],1,variablen);
473  // append newtonp to gf
474  gf[3]=newtonp;
475  // append the exponent vectors to gf
476  gf[4]=exponents;
477  return(gf);
478}
479example
480{
481   "EXAMPLE:";
482   echo=2;
483   ring r=0,(x,y,z),dp;
484   matrix M[4][1]=1,x,y,z;
485   poly f=y3+x2+xy+2xz+yz+z2+1;
486   // the Newton polytope of f is
487   list gf=groebnerFan(f);
488   // the exponent vectors of f are ordered as follows
489   gf[4];
490   // the first cone of the groebner fan has the inequalities
491   gf[1][1][1];
492   // as a string they look like
493   gf[1][1][2];
494   // and it has the extreme rays
495   print(gf[1][1][3]);
496   // the linearity space is spanned by
497   print(gf[2]);
498   // the vertices of the Newton polytope are:
499   gf[3][1];
500   // its dimension is
501   gf[3][2];
502   // np[3] contains information how the vertices are connected to each other,
503   // e.g. the 1st vertex is connected to the 2nd, 3rd and 4th vertex
504   gf[3][3][1];
505}
506
507
508
509///////////////////////////////////////////////////////////////////////////////
510/// PROCEDURES USING TOPCOM
511///////////////////////////////////////////////////////////////////////////////
512
513proc triangulations (list polygon,list #)
514"USAGE:  triangulations(polygon[,#]); list polygon, list #
515ASSUME:  polygon is a list of integer vectors of the same size representing
516         the affine coordinates of the lattice points
517PURPOSE: the procedure considers the marked polytope given as the convex hull of
518         the lattice points and with these lattice points as markings; it then
519         computes all possible triangulations of this marked polytope
520RETURN:  list, each entry corresponds to one triangulation and the ith entry is
521               itself a list of integer vectors of size three, where each integer
522               vector defines one triangle in the triangulation by telling which
523               points of the input are the vertices of the triangle
524NOTE:- the procedure calls for its computations the program points2triangs
525       from the program topcom by Joerg Rambau, Universitaet Bayreuth; it
526       therefore is necessary that this program is installed in order to use
527       this  procedure; see
528@*     http://www.uni-bayreuth.de/departments/wirtschaftsmathematik/rambau/TOPCOM
529@*   - if you only want to have the regular triangulations the procedure should
530       be called with the string 'regular' as optional argument
531@*   - the procedure creates the files /tmp/triangulationsinput and
532       /tmp/triangulationsoutput;
533       the former is used as input for points2triangs and the latter is its
534       output containing the triangulations of corresponding to points in the
535       format of points2triangs; if you wish to use this for further
536       computations with topcom, you have to call the procedure with the
537       string 'keepfiles' as optional argument
538@*   - note that an integer i in an integer vector representing a triangle
539       refers to the ith lattice point, i.e. polygon[i]; this convention is
540       different from TOPCOM's convention, where i would refer to the i-1st
541       lattice point
542EXAMPLE: example triangulations;   shows an example"
543{
544  int i,j;
545  // check for optional arguments
546  int regular,keepfiles;
547  if (size(#)>0)
548  {
549    for (i=1;i<=size(#);i++)
550    {
551      if (typeof(#[i])=="string")
552      {
553        if (#[i]=="keepfiles")
554        {
555          keepfiles=1;
556        }
557        if (#[i]=="regular")
558        {
559          regular=1;
560        }
561      }
562    }
563  }
564  // prepare the input for points2triangs by writing the input polygon in the
565  // necessary format
566  string spi="[";
567  for (i=1;i<=size(polygon);i++)
568  {
569    polygon[i][size(polygon[i])+1]=1;
570    spi=spi+"["+string(polygon[i])+"]";
571    if (i<size(polygon))
572    {
573      spi=spi+",";
574    }
575  }
576  spi=spi+"]";
577  write(":w /tmp/triangulationsinput",spi);
578  // call points2triangs
579  if (regular==1) // compute only regular triangulations
580  {
581    system("sh","cd /tmp; points2triangs --regular < triangulationsinput > triangulationsoutput");
582  }
583  else // compute all triangulations
584  {
585    system("sh","cd /tmp; points2triangs < triangulationsinput > triangulationsoutput");
586  }
587  string p2t=read("/tmp/triangulationsoutput"); // takes result of points2triangs
588  // delete the tmp-files, if no second argument is given
589  if (keepfiles==0)
590  {
591    system("sh","cd /tmp; rm -f triangulationsinput; rm -f triangulationsoutput");
592  }
593  // preprocessing of p2t if points2triangs is version >= 0.15
594  // brings p2t to the format of version 0.14
595  string np2t; // takes the triangulations in Singular format
596  for (i=1;i<=size(p2t)-2;i++)
597  {
598    if ((p2t[i]==":") and (p2t[i+1]=="=") and (p2t[i+2]=="["))
599    {
600      np2t=np2t+p2t[i]+p2t[i+1];
601      i=i+3;
602      while (p2t[i]!=":")
603      {
604        i=i+1;
605      }
606    }
607    else
608    {
609      if ((p2t[i]=="]") and (p2t[i+1]==";"))
610      {
611        np2t=np2t+p2t[i+1];
612        i=i+1;
613      }
614      else
615      {       
616        np2t=np2t+p2t[i];
617      }
618    }
619  }
620  if (p2t[size(p2t)-1]=="]")
621  {
622    np2t=np2t+p2t[size(p2t)];
623  }
624  else
625  {
626    if (np2t[size(np2t)]!=";")
627    {     
628      np2t=np2t+p2t[size(p2t)-1]+p2t[size(p2t)];
629    }
630  }
631  p2t=np2t;
632  np2t="";
633  // transform the points2triangs output of version 0.14 into Singular format
634  for (i=1;i<=size(p2t);i++)
635  {
636    if (p2t[i]=="=")
637    {
638      np2t=np2t+p2t[i]+"list(";
639      i++;
640    }
641    else
642    {
643      if (p2t[i]!=":")
644      {
645        if ((p2t[i]=="}") and (p2t[i+1]=="}"))
646        {
647          np2t=np2t+"))";
648          i++;
649        }     
650        else
651        {
652          if (p2t[i]=="{")
653          {
654            np2t=np2t+"intvec(";
655          }
656          else
657          {
658            if (p2t[i]=="}")
659            {
660              np2t=np2t+")";
661            }
662            else
663            {
664              if (p2t[i]=="[")
665              {
666                // in Topcom version 17.4 (and maybe also in earlier versions) the list
667                // of triangulations is indexed starting with index 0, in Singular
668                // we have to start with index 1
669                np2t=np2t+p2t[i]+"1+";
670              }
671              else
672              {
673                np2t=np2t+p2t[i];
674              }
675            }
676          }
677        }
678      }
679    }
680  }
681  list T;
682  execute(np2t);
683  // depending on the version of Topcom, the list T has or has not an entry T[1]
684  // if it has none, the entry should be removed
685  while (typeof(T[1])=="none")
686  {
687    T=delete(T,1);
688  }
689  // raise each index by one
690  for (i=1;i<=size(T);i++)
691  {
692    for (j=1;j<=size(T[i]);j++)
693    {
694      T[i][j]=T[i][j]+1;
695    }
696  }
697  return(T);
698}
699example
700{
701   "EXAMPLE:";
702   echo=2;
703   // the lattice points of the unit square in the plane
704   list polygon=intvec(0,0),intvec(0,1),intvec(1,0),intvec(1,1);
705   // the triangulations of this lattice point configuration are computed
706   list triang=triangulations(polygon);
707   triang;
708}
709
710/////////////////////////////////////////////////////////////////////////////
711
712proc secondaryPolytope (list polygon,list #)
713"USAGE:  secondaryPolytope(polygon[,#]); list polygon, list #
714ASSUME:  - polygon is a list of integer vectors of the same size representing
715           the affine coordinates of lattice points
716@*       - if the triangulations of the corresponding polygon have already been
717           computed with the procedure triangulations then these can be given as
718           a second (optional) argument in order to avoid doing this computation
719           again
720PURPOSE: the procedure considers the marked polytope given as the convex hull of
721         the lattice points and with these lattice points as markings; it then
722         computes the lattice points of the secondary polytope given by this
723         marked polytope which correspond to the triangulations computed by
724         the procedure triangulations
725RETURN:  list, say L, such that:
726@*             L[1] = intmat, each row gives the affine coordinates of a lattice
727                      point in the secondary polytope given by the marked
728                      polytope corresponding to polygon
729@*             L[2] = the list of corresponding triangulations
730NOTE: if the triangluations are not handed over as optional argument the
731      procedure calls for its computation of these triangulations the program
732      points2triangs from the program topcom by Joerg Rambau, Universitaet
733      Bayreuth; it therefore is necessary that this program is installed in
734      order to use this procedure; see
735@*    http://www.uni-bayreuth.de/departments/wirtschaftsmathematik/rambau/TOPCOM
736EXAMPLE: example secondaryPolytope;   shows an example"
737{
738  // compute the triangulations of the point configuration with points2triangs
739  if (size(#)==0)
740  {
741    list triangs=triangulations(polygon);
742  }
743  else
744  {
745    list triangs=#;
746  }
747  int i,j,k,l;
748  intmat N[2][2]; // is used to compute areas of triangles
749  intvec vertex;  // stores a point in the secondary polytope as
750                  // intermediate result
751  int eintrag;
752  int halt;
753  intmat secpoly[size(triangs)][size(polygon)];   // stores all lattice points
754                                                  // of the secondary polytope
755  // consider each triangulation and compute the corresponding point
756  // in the secondary polytope
757  for (i=1;i<=size(triangs);i++)
758  {
759    // for each triangulation we have to compute the coordinates
760    // corresponding to each marked point
761    for (j=1;j<=size(polygon);j++)
762    {
763      eintrag=0;
764      // for each marked point we have to consider all triangles in the
765      // triangulation which involve this particular point
766      for (k=1;k<=size(triangs[i]);k++)
767      {
768        halt=0;
769        for (l=1;(l<=3) and (halt==0);l++)
770        {
771          if (triangs[i][k][l]==j)
772          {
773            halt=1;
774            N[1,1]=polygon[triangs[i][k][3]][1]-polygon[triangs[i][k][1]][1];
775            N[1,2]=polygon[triangs[i][k][2]][1]-polygon[triangs[i][k][1]][1];
776            N[2,1]=polygon[triangs[i][k][3]][2]-polygon[triangs[i][k][1]][2];
777            N[2,2]=polygon[triangs[i][k][2]][2]-polygon[triangs[i][k][1]][2];
778            eintrag=eintrag+abs(det(N));
779          }
780        }
781      }
782      vertex[j]=eintrag;
783    }
784    secpoly[i,1..size(polygon)]=vertex;
785  }
786  return(list(secpoly,triangs));         
787}
788example
789{
790   "EXAMPLE:";
791   echo=2;
792   // the lattice points of the unit square in the plane
793   list polygon=intvec(0,0),intvec(0,1),intvec(1,0),intvec(1,1);
794   // the secondary polytope of this lattice point configuration is computed
795   list secpoly=secondaryPolytope(polygon);
796   // the points in the secondary polytope
797   print(secpoly[1]);
798   // the corresponding triangulations
799   secpoly[2];
800}
801
802///////////////////////////////////////////////////////////////////////////////
803/// PROCEDURES USING POLYMAKE AND TOPCOM
804///////////////////////////////////////////////////////////////////////////////
805
806proc secondaryFan (list polygon,list #)
807"USAGE:  secondaryFan(polygon[,#]); list polygon, list #
808ASSUME:  - polygon is a list of integer vectors of the same size representing
809           the affine coordinates of lattice points
810@*       - if the triangulations of the corresponding polygon have already been
811           computed with the procedure triangulations then these can be given
812           as a second (optional) argument in order to avoid doing this
813           computation again
814PURPOSE: the procedure considers the marked polytope given as the convex hull of
815         the lattice points and with these lattice points as markings; it then
816         computes the lattice points of the secondary polytope given by this
817         marked polytope which correspond to the triangulations computed by
818         the procedure triangulations
819RETURN:  list, the ith entry of L[1] contains information about the ith cone in
820               the secondary fan of the polygon, i.e. the cone dual to the
821               ith vertex of the secondary polytope
822@*             L[1][i][1] = integer matrix representing the inequalities which
823                            describe the cone dual to the ith vertex
824@*             L[1][i][2] = a list which contains the inequalities represented
825                            by L[1][i][1] as a list of strings, where we use the
826                            variables x(1),...,x(n)
827@*             L[1][i][3] = only present if 'er' is set to 1; in that case it is
828                            an interger matrix whose rows are the extreme rays
829                            of the cone
830@*             L[2] = is an integer matrix whose rows span the linearity space
831                      of the fan, i.e. the linear space which is contained in
832                      each cone
833@*             L[3] = the secondary polytope in the format of the procedure
834                      polymakePolytope
835@*             L[4] = the list of triangulations corresponding to the vertices
836                      of the secondary polytope
837NOTE:- the procedure calls for its computation polymake by Ewgenij Gawrilow,
838       TU Berlin and Michael Joswig, so it only works if polymake is installed;
839       see http://www.math.tu-berlin.de/polymake/
840@*   - in the optional argument # it is possible to hand over other names for
841       the variables to be used -- be careful, the format must be correct and
842       that is not tested, e.g. if you want the variable names to be
843       u00,u10,u01,u11 then you must hand over the string 'u11,u10,u01,u11'
844@*   - if the triangluations are not handed over as optional argument the
845       procedure calls for its computation of these triangulations the program
846       points2triangs from the program topcom by Joerg Rambau, Universitaet
847       Bayreuth; it therefore is necessary that this program is installed in
848       order to use this procedure; see
849@*     http://www.uni-bayreuth.de/departments/wirtschaftsmathematik/rambau/TOPCOM
850EXAMPLE: example secondaryFan;   shows an example"
851{
852  if (size(#)==0)
853  {
854    list triang=triangulations(polygon);
855  }
856  else
857  {
858    list triang=#[1];
859  } 
860  list sp=secondaryPolytope(polygon,triang);
861  list spp=polymakePolytope(sp[1]);
862  list sf=normalFan(spp[1],spp[4],spp[3],1);
863  return(list(sf[1],sf[2],spp,triang));
864}
865example
866{
867   "EXAMPLE:";
868   echo=2;
869   // the lattice points of the unit square in the plane
870   list polygon=intvec(0,0),intvec(0,1),intvec(1,0),intvec(1,1);
871   // the secondary polytope of this lattice point configuration is computed
872   list secfan=secondaryFan(polygon);
873   // the number of cones in the secondary fan of the polygon
874   size(secfan[1]);
875   // the inequalities of the first cone as matrix are:
876   print(secfan[1][1][1]);
877   // the inequalities of the first cone as string are:
878   print(secfan[1][1][2]);
879   // the rows of the following matrix are the extreme rays of the first cone:
880   print(secfan[1][1][3]);
881   // each cone contains the linearity space spanned by:
882   print(secfan[2]);
883   // the points in the secondary polytope
884   print(secfan[3][1]);
885   // the corresponding triangulations
886   secfan[4];
887}
888
889
890////////////////////////////////////////////////////////////////////////////////
891/// PROCEDURES CONCERNED WITH PLANAR POLYGONS
892////////////////////////////////////////////////////////////////////////////////
893
894proc cycleLength (list boundary,intvec interior)
895"USAGE:  cycleLength(boundary,interior); list boundary, intvec interior
896ASSUME:  boundary is a list of integer vectors describing a cycle in some
897         convex lattice polygon around the lattice point interior ordered
898         clock wise
899RETURN:  string, the cycle length of the corresponding cycle in the dual
900                 tropical curve
901EXAMPLE: example cycleLength;   shows an example"
902{
903  int j;
904  // create a ring whose variables are indexed by the points in
905  // boundary resp. by interior
906  string rst="ring cyclering=0,(u"+string(interior[1])+string(interior[2]);
907  for (j=1;j<=size(boundary);j++)
908  {
909    rst=rst+",u"+string(boundary[j][1])+string(boundary[j][2]);
910  }
911  rst=rst+"),lp;";
912  execute(rst);
913  // add the first and second point at the end of boundary
914  boundary[size(boundary)+1]=boundary[1];
915  boundary[size(boundary)+1]=boundary[2];
916  poly cl,summand; // takes the cycle length
917  matrix N1[2][2]; // used to compute the area of a triangle
918  matrix N2[2][2]; // used to compute the area of a triangle
919  matrix N3[2][2]; // used to compute the area of a triangle
920  // for each original point in boundary compute its contribution to the cycle
921  for (j=2;j<=size(boundary)-1;j++)
922  {
923    N1=boundary[j-1]-interior,boundary[j]-interior;
924    N2=boundary[j]-interior,boundary[j+1]-interior;
925    N3=boundary[j+1]-interior,boundary[j-1]-interior;
926    execute("summand=-u"+string(boundary[j][1])+string(boundary[j][2])+"+u"+string(interior[1])+string(interior[2])+";");
927    summand=summand*(det(N1)+det(N2)+det(N3))/(det(N1)*det(N2));
928    cl=cl+summand;
929  }
930  return(string(cl));
931}
932example
933{
934   "EXAMPLE:";
935   echo=2;
936   // the integer vectors in boundary are lattice points on the boundary
937   // of a convex lattice polygon in the plane
938   list boundary=intvec(0,0),intvec(0,1),intvec(0,2),intvec(2,2),
939                 intvec(2,1),intvec(2,0);
940   // interior is a lattice point in the interior of this lattice polygon
941   intvec interior=1,1;
942   // compute the general cycle length of a cycle of the corresponding cycle
943   // in the dual tropical curve, note that (0,1) and (2,1) do not contribute
944   cycleLength(boundary,interior);
945}
946
947/////////////////////////////////////////////////////////////////////////////
948
949proc splitPolygon (list markings)
950"USAGE:  splitPolygon (markings);  markings list
951ASSUME:  markings is a list of integer vectors representing lattice points in
952         the plane which we consider as the marked points of the convex lattice
953         polytope spanned by them
954PURPOSE: split the marked points in the vertices, the points on the facets
955         which are not vertices, and the interior points
956RETURN:  list, L consisting of three lists
957@*             L[1]    : represents the vertices the polygon ordered clockwise
958@*                       L[1][i][1] = intvec, the coordinates of the ith vertex
959@*                       L[1][i][2] = int, the position of L[1][i][1] in markings
960@*             L[2][i] : represents the lattice points on the facet of the
961                         polygon with endpoints L[1][i] and L[1][i+1]
962                         (i considered modulo size(L[1]))
963@*                       L[2][i][j][1] = intvec, the coordinates of the jth
964                                                 lattice point on that facet
965@*                       L[2][i][j][2] = int, the position of L[2][i][j][1]
966                                              in markings
967@*             L[3]    : represents the interior lattice points of the polygon
968@*                       L[3][i][1] = intvec, coordinates of ith interior point
969@*                       L[3][i][2] = int, the position of L[3][i][1] in markings
970EXAMPLE: example splitPolygon;   shows an example"
971{
972  list vert; // stores the result
973  // compute the boundary of the polygon in an oriented way
974  list pb=findOrientedBoundary(markings);
975  // the vertices are just the second entry of pb
976  vert[1]=pb[2];
977  int i,j,k;      // indices
978  list boundary;  // stores the points on the facets of the
979                  // polygon which are not vertices
980  // append to the boundary points as well as to the vertices
981  // the first vertex a second time
982  pb[1]=pb[1]+list(pb[1][1]);
983  pb[2]=pb[2]+list(pb[2][1]);
984  // for each vertex find all points on the facet of the polygon with this vertex
985  // and the next vertex as endpoints
986  int z=2;
987  for (i=1;i<=size(vert[1]);i++)
988  {
989    j=1;
990    list facet; // stores the points on this facet which are not vertices
991    // while the next vertex is not reached, store the boundary lattice point
992    while (pb[1][z]!=pb[2][i+1])
993    {
994      facet[j]=pb[1][z];
995      j++;
996      z++;
997    }
998    // store the points on the ith facet as boundary[i]
999    boundary[i]=facet;
1000    kill facet;
1001    z++;
1002  }
1003  // store the information on the boundary in vert[2]
1004  vert[2]=boundary;
1005  // find the remaining points in the input which are not on
1006  // the boundary by checking
1007  // for each point in markings if it is contained in pb[1]
1008  list interior=markings;
1009  for (i=size(interior);i>=1;i--)
1010  {
1011    for (j=1;j<=size(pb[1])-1;j++)
1012    {
1013      if (interior[i]==pb[1][j])
1014      {
1015        interior=delete(interior,i);
1016        j=size(pb[1]);
1017      }
1018    }
1019  }
1020  // store the interior points in vert[3]
1021  vert[3]=interior;
1022  // add to each point in vert the index which it gets from
1023  // its position in the input markings;
1024  // do so for ver[1]
1025  for (i=1;i<=size(vert[1]);i++)
1026  {
1027    j=1;
1028    while (markings[j]!=vert[1][i])
1029    {
1030      j++;
1031    }
1032    vert[1][i]=list(vert[1][i],j);
1033  }
1034  // do so for ver[2]
1035  for (i=1;i<=size(vert[2]);i++)
1036  {
1037    for (k=1;k<=size(vert[2][i]);k++)
1038    {
1039      j=1;
1040      while (markings[j]!=vert[2][i][k])
1041      {
1042        j++;
1043      }
1044      vert[2][i][k]=list(vert[2][i][k],j);
1045    }
1046  }
1047  // do so for ver[3]
1048  for (i=1;i<=size(vert[3]);i++)
1049  {
1050    j=1;
1051    while (markings[j]!=vert[3][i])
1052    {
1053      j++;
1054    }
1055    vert[3][i]=list(vert[3][i],j);
1056  } 
1057  return(vert);
1058}
1059example
1060{
1061   "EXAMPLE:";
1062   echo=2;
1063   // the lattice polygon spanned by the points (0,0), (3,0) and (0,3)
1064   // with all integer points as markings
1065   list polygon=intvec(1,1),intvec(3,0),intvec(2,0),intvec(1,0),
1066                intvec(0,0),intvec(2,1),intvec(0,1),intvec(1,2),
1067                intvec(0,2),intvec(0,3);
1068   // split the polygon in its vertices, its facets and its interior points
1069   list sp=splitPolygon(polygon);
1070   // the vertices
1071   sp[1];
1072   // the points on facets which are not vertices
1073   sp[2];
1074   // the interior points
1075   sp[3];
1076}
1077
1078
1079/////////////////////////////////////////////////////////////////////////////
1080
1081proc eta (list triang,list polygon)
1082"USAGE:  eta(triang,polygon);  triang, polygon list
1083ASSUME:  polygon has the format of the output of splitPolygon, i.e. it is a
1084         list with three entries describing a convex lattice polygon in the
1085         following way:
1086@*       polygon[1] : is a list of lists; for each i the entry polygon[1][i][1]
1087                      is a lattice point which is a vertex of the lattice
1088                      polygon, and polygon[1][i][2] is an integer assigned to
1089                      this lattice point as identifying index
1090@*       polygon[2] : is a list of lists; for each vertex of the polygon,
1091                      i.e. for each entry in polygon[1], it contains a list
1092                      polygon[2][i], which contains the lattice points on the
1093                      facet with endpoints polygon[1][i] and polygon[1][i+1]
1094                      - i considered mod size(polygon[1]);
1095                      each such lattice point contributes an entry
1096                      polygon[2][i][j][1] which is an integer
1097                      vector giving the coordinate of the lattice point and an
1098                      entry polygon[2][i][j][2] which is the identifying index
1099@*       polygon[3] : is a list of lists, where each entry corresponds to a
1100                      lattice point in the interior of the polygon, with
1101                      polygon[3][j][1] being the coordinates of the point
1102                      and polygon[3][j][2] being the identifying index;
1103@*       triang is a list of integer vectors all of size three describing a
1104         triangulation of the polygon described by polygon; if an entry of
1105         triang is the vector (i,j,k) then the triangle is built by the vertices
1106         with indices i, j and k
1107RETURN:  intvec, the integer vector eta describing that vertex of the Newton
1108                 polytope discriminant of the polygone whose dual cone in the
1109                 Groebner fan contains the cone of the secondary fan of the
1110                 polygon corresponding to the given triangulation
1111NOTE:  for a better description of eta see Gelfand, Kapranov,
1112       Zelevinski: Discriminants, Resultants and multidimensional Determinants.
1113       Chapter 10.
1114EXAMPLE: example eta;   shows an example"
1115{
1116  int i,j,k,l,m,n; // index variables
1117  list ordpolygon;   // stores the lattice points in the order
1118                     // used in the triangulation
1119  list triangarea; // stores the areas of the triangulations
1120  intmat N[2][2];  // used to compute triangle areas
1121  // 1) store the lattice points in the order used in the triangulation
1122  // go first through all vertices of the polytope
1123  for (j=1;j<=size(polygon[1]);j++)
1124  {
1125    ordpolygon[polygon[1][j][2]]=polygon[1][j][1];
1126  }
1127  // then consider all inner points
1128  for (j=1;j<=size(polygon[3]);j++)
1129  {
1130    ordpolygon[polygon[3][j][2]]=polygon[3][j][1];
1131  }
1132  // finally consider all lattice points on the boundary which are not vertices
1133  for (j=1;j<=size(polygon[2]);j++)
1134  {
1135    for (i=1;i<=size(polygon[2][j]);i++)
1136    {
1137      ordpolygon[polygon[2][j][i][2]]=polygon[2][j][i][1];
1138    }
1139  }
1140  // 2) compute for each triangle in the triangulation the area of the triangle
1141  for (i=1;i<=size(triang);i++)
1142  {
1143    // Note that the ith lattice point in orderedpolygon has the
1144    // number i-1 in the triangulation!
1145    N=ordpolygon[triang[i][1]]-ordpolygon[triang[i][2]],ordpolygon[triang[i][1]]-ordpolygon[triang[i][3]];
1146    triangarea[i]=abs(det(N));
1147  }
1148  intvec ETA;        // stores the eta_ij
1149  int etaij;         // stores the part of eta_ij during computations
1150                     // which comes from triangle areas
1151  int seitenlaenge;  // stores the part of eta_ij during computations
1152                     // which comes from boundary facets
1153  list seiten;       // stores the lattice points on facets of the polygon
1154  intvec v;          // used to compute a facet length
1155  // 3) store first in seiten[i] all lattice points on the facet
1156  //    connecting the ith vertex,
1157  //    i.e. polygon[1][i], with the i+1st vertex, i.e. polygon[1][i+1],
1158  //    where we replace i+1
1159  //    1 if i=size(polygon[1]);
1160  //    then append the last entry of seiten once more at the very
1161  //    beginning of seiten, so
1162  //    that the index is shifted by one
1163  for (i=1;i<=size(polygon[1]);i++)
1164  {
1165    if (i<size(polygon[1]))
1166    {
1167      seiten[i]=list(polygon[1][i])+polygon[2][i]+list(polygon[1][i+1]);
1168    }
1169    else
1170    {
1171      seiten[i]=list(polygon[1][i])+polygon[2][i]+list(polygon[1][1]);
1172    }
1173  }
1174  seiten=insert(seiten,seiten[size(seiten)],0);
1175  // 4) compute the eta_ij for all vertices of the polygon
1176  for (j=1;j<=size(polygon[1]);j++)
1177  {
1178    // the vertex itself contributes a 1
1179    etaij=1;
1180    // check for each triangle in the triangulation ...
1181    for (k=1;k<=size(triang);k++)
1182    {
1183      // ... if the vertex is actually a vertex of the triangle ...
1184      if ((polygon[1][j][2]==triang[k][1]) or (polygon[1][j][2]==triang[k][2]) or (polygon[1][j][2]==triang[k][3]))
1185      {
1186        // ... if so, add the area of the triangle to etaij
1187        etaij=etaij+triangarea[k];
1188        // then check if that triangle has a facet which is contained
1189        // in one of the
1190        // two facets of the polygon which are adjecent to the given vertex ...
1191        // these two facets are seiten[j] and seiten[j+1]
1192        for (n=j;n<=j+1;n++)
1193        {
1194          // check for each lattice point in the facet of the polygon ...
1195          for (l=1;l<=size(seiten[n]);l++)
1196          {
1197            // ... and for each lattice point in the triangle ...
1198            for (m=1;m<=size(triang[k]);m++)
1199            {
1200              // ... if they coincide and are not the vertex itself ...
1201              if ((seiten[n][l][2]==triang[k][m]) and (seiten[n][l][2]!=polygon[1][j][2]))
1202              {
1203                // if so, then compute the vector pointing from this
1204                // lattice point to the vertex
1205                v=polygon[1][j][1]-seiten[n][l][1];
1206                // and the lattice length of this vector has to be
1207                // subtracted from etaij
1208                etaij=etaij-abs(gcd(v[1],v[2]));
1209              }
1210            }
1211          }
1212        }
1213      }
1214    }
1215    // store etaij in the list
1216    ETA[polygon[1][j][2]]=etaij;
1217  }
1218  // 5) compute the eta_ij for all lattice points on the facets
1219  //    of the polygon which are not vertices, these are the
1220  //    lattice points in polygon[2][1] to polygon[2][size(polygon[1])]
1221  for (i=1;i<=size(polygon[2]);i++)
1222  {
1223    for (j=1;j<=size(polygon[2][i]);j++)
1224    {     
1225      // initialise etaij
1226      etaij=0;
1227      // initialise seitenlaenge
1228      seitenlaenge=0;
1229      // check for each triangle in the triangulation ...
1230      for (k=1;k<=size(triang);k++)
1231      {
1232        // ... if the vertex is actually a vertex of the triangle ...
1233        if ((polygon[2][i][j][2]==triang[k][1]) or (polygon[2][i][j][2]==triang[k][2]) or (polygon[2][i][j][2]==triang[k][3]))
1234        {
1235          // ... if so, add the area of the triangle to etaij
1236          etaij=etaij+triangarea[k];
1237          // then check if that triangle has a facet which is contained in the
1238          // facet of the polygon which contains the lattice point in question,
1239          // this is the facet seiten[i+1];
1240          // check for each lattice point in the facet of the polygon ...
1241          for (l=1;l<=size(seiten[i+1]);l++)
1242          {
1243            // ... and for each lattice point in the triangle ...
1244            for (m=1;m<=size(triang[k]);m++)
1245            {           
1246              // ... if they coincide and are not the vertex itself ...
1247              if ((seiten[i+1][l][2]==triang[k][m]) and (seiten[i+1][l][2]!=polygon[2][i][j][2]))
1248              {
1249                // if so, then compute the vector pointing from
1250                // this lattice point to the vertex
1251                v=polygon[2][i][j][1]-seiten[i+1][l][1];
1252                // and the lattice length of this vector contributes
1253                // to seitenlaenge
1254                seitenlaenge=seitenlaenge+abs(gcd(v[1],v[2]));
1255              }
1256            }
1257          }
1258        }
1259      }
1260      // if the lattice point was a vertex of any triangle
1261      // in the triangulation ...
1262      if (etaij!=0)
1263      {
1264        // then eta_ij is the sum of the triangle areas minus seitenlaenge
1265        ETA[polygon[2][i][j][2]]=etaij-seitenlaenge;
1266      }
1267      else
1268      {
1269        // otherwise it is just zero
1270        ETA[polygon[2][i][j][2]]=0;
1271      }
1272    }
1273  }
1274  // 4) compute the eta_ij for all inner lattice points of the polygon
1275  for (j=1;j<=size(polygon[3]);j++)
1276  {
1277    // initialise etaij
1278    etaij=0;
1279    // check for each triangle in the triangulation ...
1280    for (k=1;k<=size(triang);k++)
1281    {
1282      // ... if the vertex is actually a vertex of the triangle ...
1283      if ((polygon[3][j][2]==triang[k][1]) or (polygon[3][j][2]==triang[k][2]) or (polygon[3][j][2]==triang[k][3]))
1284      {
1285        // ... if so, add the area of the triangle to etaij
1286        etaij=etaij+triangarea[k];
1287      }
1288    }
1289    // store etaij in ETA
1290    ETA[polygon[3][j][2]]=etaij;
1291  }
1292  return(ETA);
1293}
1294example
1295{
1296   "EXAMPLE:";
1297   echo=2;
1298   // the lattice polygon spanned by the points (0,0), (3,0) and (0,3)
1299   // with all integer points as markings
1300   list polygon=intvec(1,1),intvec(3,0),intvec(2,0),intvec(1,0),
1301                intvec(0,0),intvec(2,1),intvec(0,1),intvec(1,2),
1302                intvec(0,2),intvec(0,3);
1303   // split the polygon in its vertices, its facets and its interior points
1304   list sp=splitPolygon(polygon);
1305   // define a triangulation by connecting the only interior point
1306   //        with the vertices
1307   list triang=intvec(1,2,5),intvec(1,5,10),intvec(1,5,10);
1308   // compute the eta-vector of this triangulation
1309   eta(triang,sp);
1310}
1311 
1312/////////////////////////////////////////////////////////////////////////////
1313
1314proc findOrientedBoundary (list polygon)
1315"USAGE: findOrientedBoundary(polygon); polygon list
1316ASSUME: polygon is a list of integer vectors defining integer lattice points
1317        in the plane
1318RETURN: list l with the following interpretation
1319@*            l[1] = list of integer vectors such that the polygonal path
1320                     defined by these is the boundary of the convex hull of
1321                     the lattice points in polygon
1322@*            l[2] = list, the redundant points in l[1] have been removed
1323EXAMPLE:     example findOrientedBoundary;   shows an example"
1324{
1325  // Order the vertices such that passing from one to the next we travel along
1326  // the boundary of the convex hull of the vertices clock wise
1327  int d,k,i,j;
1328  intmat D[2][2];
1329  /////////////////////////////////////
1330  // Treat first the pathological cases that the polygon is not two-dimensional:
1331  /////////////////////////////////////
1332  // if the polygon is empty or only one point or a line segment of two points
1333  if (size(polygon)<=2)
1334  {
1335    return(list(polygon,polygon));
1336  }
1337  // check is the polygon is only a line segment given by more than two points;
1338  // for this first compute sum of the absolute values of the determinants
1339  // of the matrices whose
1340  // rows are the vectors pointing from the first to the second point
1341  // and from the
1342  // the first point to the ith point for i=3,...,size(polygon);
1343  // if this sum is zero
1344  // then the polygon is a line segment and we have to find its end points
1345  d=0;
1346  for (i=3;i<=size(polygon);i++)
1347  {
1348    D=polygon[2]-polygon[1],polygon[i]-polygon[1];
1349    d=d+abs(det(D));
1350  }
1351  if (d==0) // then polygon is a line segment
1352  {
1353    intmat laenge[size(polygon)][size(polygon)];
1354    intvec mp;
1355    //   for this collect first all vectors pointing from one lattice
1356    //   point to the next,
1357    //   compute their pairwise angles and their lengths
1358    for (i=1;i<=size(polygon)-1;i++)
1359    {     
1360      for (j=i+1;j<=size(polygon);j++)
1361      {
1362        mp=polygon[i]-polygon[j];
1363        laenge[i,j]=abs(gcd(mp[1],mp[2]));
1364      }
1365    }
1366    mp=maxPosInIntmat(laenge);
1367    list endpoints=polygon[mp[1]],polygon[mp[2]];
1368    intvec abstand;
1369    for (i=1;i<=size(polygon);i++)
1370    {
1371      abstand[i]=0;
1372      if (i<mp[1])
1373      {
1374        abstand[i]=laenge[i,mp[1]];
1375      }
1376      if (i>mp[1])
1377      {
1378        abstand[i]=laenge[mp[1],i];
1379      }
1380    }
1381    polygon=sortlistbyintvec(polygon,abstand);
1382    return(list(polygon,endpoints));
1383  } 
1384  ///////////////////////////////////////////////////////////////
1385  list orderedvertices;  // stores the vertices in an ordered way
1386  list minimisedorderedvertices;  // stores the vertices in an ordered way;
1387                                  // redundant ones removed
1388  list comparevertices; // stores vertices which should be compared to
1389                        // the testvertex
1390  orderedvertices[1]=polygon[1]; // set the starting vertex
1391  minimisedorderedvertices[1]=polygon[1]; // set the starting vertex
1392  intvec testvertex=polygon[1];  //vertex to which the others have to be compared
1393  intvec startvertex=polygon[1]; // keep the starting vertex to test,
1394                                 // when the end is reached
1395  int endtest;                   // is set to one, when the end is reached
1396  int startvertexfound;// is 1, once for some testvertex a candidate
1397                       // for the next vertex has been found
1398  polygon=delete(polygon,1);    // delete the testvertex
1399  intvec v,w;
1400  int l=1;  // counts the vertices
1401  // the basic idea is that a vertex can be
1402  // the next one on the boundary if all other vertices
1403  // lie to the right of the vector v pointing
1404  // from the testvertex to this one; this can be tested
1405  // by checking if the determinant of the 2x2-matrix
1406  // with first column v and second column the vector w,
1407  // pointing from the testvertex to the new vertex,
1408  // is non-positive; if this is the case for all
1409  // new vertices, then the one in consideration is
1410  // a possible choice for the next vertex on the boundary
1411  // and it is stored in naechste; we can then order
1412  // the candidates according to their distance from
1413  // the testvertex; then they occur on the boundary in that order!
1414  while (endtest==0)
1415  {
1416    list naechste;  // stores the possible choices for the next vertex
1417    k=1;
1418    for (i=1;i<=size(polygon);i++)
1419    {
1420      d=0;  // stores the value of the determinant of (v,w)
1421      v=polygon[i]-testvertex; // points from the testvertex to the ith vertex
1422      comparevertices=delete(polygon,i); // we needn't compare v to itself
1423      // we should compare v to the startvertex-testvertex;
1424      // in the first calling of the loop
1425      // this is irrelevant since the difference will be zero;
1426      // however, later on it will
1427      // be vital, since we delete the vertices
1428      // which we have already tested from the list
1429      // of all vertices, and when all vertices
1430      // on the boundary have been found we would
1431      // therefore find a vertex in the interior
1432      // as candidate; but always testing against
1433      // the starting vertex, this cannot happen
1434      comparevertices[size(comparevertices)+1]=startvertex;
1435      for (j=1;(j<=size(comparevertices)) and (d<=0);j++)
1436      {
1437        w=comparevertices[j]-testvertex; // points form the testvertex
1438                                         // to the jth vertex
1439        D=v,w;
1440        d=det(D);
1441      }
1442      if (d<=0) // if all determinants are non-positive,
1443      { // then the ith vertex is a candidate
1444        naechste[k]=list(polygon[i],i,scalarproduct(v,v));// we store the vertex,
1445                                                          //its position, and its
1446        k++; // distance from the testvertex
1447      }
1448    }
1449    if (size(naechste)>0) // then a candidate for the next vertex has been found
1450    {     
1451      startvertexfound=1; // at least once a candidate has been found
1452      naechste=sortlist(naechste,3);  // we order the candidates according
1453                                      // to their distance from testvertex;
1454      for (j=1;j<=size(naechste);j++) // then we store them in this
1455      { // order in orderedvertices
1456        l++;
1457        orderedvertices[l]=naechste[j][1];
1458      }
1459      testvertex=naechste[size(naechste)][1];  // we store the last one as
1460                                               // next testvertex;
1461      // store the next corner of NSD
1462      minimisedorderedvertices[size(minimisedorderedvertices)+1]=testvertex;
1463      naechste=sortlist(naechste,2); // then we reorder the vertices
1464                                     // according to their position
1465      for (j=size(naechste);j>=1;j--) // and we delete them from the vertices
1466      {
1467        polygon=delete(polygon,naechste[j][2]);
1468      }
1469    }
1470    else // that means either that the vertex was inside the polygon,
1471    {    // or that we have reached the last vertex on the boundary
1472         // of the polytope
1473      if (startvertexfound==0) // the vertex was in the interior;
1474      { // we delete it and start all over again
1475        orderedvertices[1]=polygon[1];
1476        minimisedorderedvertices[1]=polygon[1];
1477        testvertex=polygon[1];
1478        startvertex=polygon[1];
1479        polygon=delete(polygon,1);
1480      }
1481      else // we have reached the last vertex on the boundary of
1482      { // the polytope and can stop
1483        endtest=1;
1484      }
1485    }
1486    kill naechste;
1487  }
1488  // test if the first vertex in minimisedorderedvertices
1489  // is on the same line with the second and
1490  // the last, i.e. if we started our search in the
1491  // middle of a face; if so, delete it
1492  v=minimisedorderedvertices[2]-minimisedorderedvertices[1];
1493  w=minimisedorderedvertices[size(minimisedorderedvertices)]-minimisedorderedvertices[1];
1494  D=v,w;
1495  if (det(D)==0)
1496  {
1497    minimisedorderedvertices=delete(minimisedorderedvertices,1);
1498  }
1499  // test if the first vertex in minimisedorderedvertices
1500  // is on the same line with the two
1501  // last ones, i.e. if we started our search at the end of a face;
1502  // if so, delete it
1503  v=minimisedorderedvertices[size(minimisedorderedvertices)-1]-minimisedorderedvertices[1];
1504  w=minimisedorderedvertices[size(minimisedorderedvertices)]-minimisedorderedvertices[1];
1505  D=v,w;
1506  if (det(D)==0)
1507  {
1508    minimisedorderedvertices=delete(minimisedorderedvertices,size(minimisedorderedvertices));
1509  }
1510  return(list(orderedvertices,minimisedorderedvertices));
1511}
1512example
1513{
1514   "EXAMPLE:";
1515   echo=2;
1516// the following lattice points in the plane define a polygon
1517   list polygon=intvec(0,0),intvec(3,1),intvec(1,0),intvec(2,0),
1518                intvec(1,1),intvec(3,2),intvec(1,2),intvec(2,3),
1519                intvec(2,4);
1520// we compute its boundary
1521   list boundarypolygon=findOrientedBoundary(polygon);
1522// the points on the boundary ordered clockwise are boundarypolygon[1]
1523   boundarypolygon[1];
1524// the vertices of the boundary are boundarypolygon[2]
1525   boundarypolygon[2];
1526}
1527
1528
1529/////////////////////////////////////////////////////////////////////////////
1530
1531proc cyclePoints (list triang,list points,int pt)
1532"USAGE:      cyclePoints(triang,points,pt)  triang,points list, pt int
1533ASSUME:      - points is a list of integer vectors describing the lattice
1534               points of a marked polygon;
1535@*           - triang is a list of integer vectors describing a triangulation
1536               of the marked polygon in the sense that an integer vector of
1537               the form (i,j,k) describes the triangle formed by polygon[i],
1538               polygon[j] and polygon[k];
1539@*           - pt is an integer between 1 and size(points), singling out a
1540               lattice point among the marked points
1541PURPOSE:     consider the convex lattice polygon, say P, spanned by all lattice
1542             points in points which in the triangulation triang are connected
1543             to the point points[pt]; the procedure computes all marked points
1544             in points which lie on the boundary of that polygon, ordered
1545             clockwise
1546RETURN:      list, of integer vectors which are the coordinates of the lattice
1547                   points on the boundary of the above mentioned polygon P, if
1548                   this polygon is not the empty set (that would be the case if
1549                   points[pt] is not a vertex of any triangle in the
1550                   triangulation); otherwise return the empty list
1551EXAMPLE:     example cyclePoints;   shows an example"
1552{
1553  int i,j; // indices
1554  list v;  // saves the indices of lattice points connected to the
1555           // interior point in the triangulation
1556  // save all points in triangulations containing pt in v
1557  for (i=1;i<=size(triang);i++)
1558  {
1559    if ((triang[i][1]==pt) or (triang[i][2]==pt) or (triang[i][3]==pt))
1560    {
1561      j++;
1562      v[3*j-2]=triang[i][1];
1563      v[3*j-1]=triang[i][2];
1564      v[3*j]=triang[i][3];
1565    }
1566  }
1567  if (size(v)==0)
1568  {
1569    return(list());
1570  }
1571  // remove pt itself and redundancies in v
1572  for (i=size(v);i>=1;i--)
1573  {
1574    j=1;
1575    while ((j<i) and (v[i]!=v[j]))
1576    {
1577      j++;
1578    }
1579    if ((j<i) or (v[i]==pt))
1580    {
1581      v=delete(v,i);
1582    }
1583  }
1584  // save in pts the coordinates of the points with indices in v
1585  list pts;
1586  for (i=1;i<=size(v);i++)
1587  {
1588    pts[i]=points[v[i]];
1589  }
1590  // consider the convex polytope spanned by the points in pts,
1591  // find the points on the
1592  // boundary and order them clockwise
1593  return(findOrientedBoundary(pts)[1]);
1594}
1595example
1596{
1597   "EXAMPLE:";
1598   echo=2;
1599   // the lattice polygon spanned by the points (0,0), (3,0) and (0,3)
1600   // with all integer points as markings
1601   list points=intvec(1,1),intvec(3,0),intvec(2,0),intvec(1,0),
1602               intvec(0,0),intvec(2,1),intvec(0,1),intvec(1,2),
1603               intvec(0,2),intvec(0,3);
1604   // define a triangulation
1605   list triang=intvec(1,2,5),intvec(1,5,7),intvec(1,7,9),intvec(8,9,10),
1606               intvec(1,8,9),intvec(1,2,8);
1607   // compute the points connected to (1,1) in triang
1608   cyclePoints(triang,points,1);
1609}
1610
1611/////////////////////////////////////////////////////////////////////////////
1612
1613proc latticeArea (list polygon)
1614"USAGE:  latticeArea(polygon);   polygon list
1615ASSUME:  polygon is a list of integer vectors in the plane
1616RETURN:  int, the lattice area of the convex hull of the lattice points in
1617              polygon, i.e. twice the Euclidean area
1618EXAMPLE: example polygonlatticeArea;   shows an example"
1619{
1620  list pg=findOrientedBoundary(polygon)[2];
1621  int area;
1622  intmat M[2][2];
1623  for (int i=2;i<=size(pg)-1;i++)
1624  {
1625    M[1,1..2]=pg[i]-pg[1];
1626    M[2,1..2]=pg[i+1]-pg[1];
1627    area=area+abs(det(M));
1628  }
1629  return(area);
1630}
1631example
1632{
1633   "EXAMPLE:";
1634   echo=2;
1635   // define a polygon with lattice area 5
1636   list polygon=intvec(1,2),intvec(1,0),intvec(2,0),intvec(1,1),
1637                intvec(2,1),intvec(0,0);
1638   latticeArea(polygon);
1639}
1640
1641/////////////////////////////////////////////////////////////////////////////
1642
1643proc picksFormula (list polygon)
1644"USAGE:  picksFormula(polygon);   polygon list
1645ASSUME:  polygon is a list of integer vectors in the plane and consider their
1646         convex hull C
1647RETURN:  list, L of three integersthe
1648@*             L[1] : the lattice area of C, i.e. twice the Euclidean area
1649@*             L[2] : the number of lattice points on the boundary of C
1650@*             L[3] : the number of interior lattice points of C
1651NOTE: the integers in L are related by Pick's formula, namely: L[1]=L[2]+2*L[3]-2
1652EXAMPLE: example picksFormula;   shows an example"
1653{
1654  list pg=findOrientedBoundary(polygon)[2];
1655  int area,bdpts,i;
1656  intmat M[2][2];
1657  // compute the lattice area of the polygon, i.e. twice the Euclidean area
1658  for (i=2;i<=size(pg)-1;i++)
1659  {
1660    M[1,1..2]=pg[i]-pg[1];
1661    M[2,1..2]=pg[i+1]-pg[1];
1662    area=area+abs(det(M));
1663  }
1664  // compute the number of lattice points on the boundary
1665  intvec edge;
1666  pg[size(pg)+1]=pg[1];
1667  for (i=1;i<=size(pg)-1;i++)
1668  {
1669    edge=pg[i]-pg[i+1];
1670    bdpts=bdpts+abs(gcd(edge[1],edge[2]));
1671  }
1672  // Pick's formula says that the lattice area A, the number g of interior
1673  // points and
1674  // the number b of boundary points are connected by the formula: A=b+2g-2
1675  return(list(area,bdpts,(area-bdpts+2) div 2));
1676}
1677example
1678{
1679   "EXAMPLE:";
1680   echo=2;
1681   // define a polygon with lattice area 5
1682   list polygon=intvec(1,2),intvec(1,0),intvec(2,0),intvec(1,1),
1683                intvec(2,1),intvec(0,0);
1684   list pick=picksFormula(polygon);
1685   // the lattice area of the polygon is:
1686   pick[1];
1687   // the number of lattice points on the boundary is:
1688   pick[2];
1689   // the number of interior lattice points is:
1690   pick[3];
1691   // the number's are related by Pick's formula:
1692   pick[1]-pick[2]-2*pick[3]+2;
1693}
1694
1695/////////////////////////////////////////////////////////////////////////////
1696
1697proc ellipticNF (list polygon)
1698"USAGE:  ellipticNF(polygon);   polygon list
1699ASSUME:  polygon is a list of integer vectors in the plane such that their
1700         convex hull C has precisely one interior lattice point; i.e. C is the
1701         Newton polygon of an elliptic curve
1702PURPOSE: compute the normal form of the polygon with respect to the unimodular
1703         affine transformations T=A*x+v; there are sixteen different normal forms
1704         (see e.g. Bjorn Poonen, Fernando Rodriguez-Villegas: Lattice Polygons
1705                   and the number 12.  Amer. Math. Monthly  107  (2000),  no. 3,
1706                   238--250.)
1707RETURN:  list, L such that
1708@*             L[1] : list whose entries are the vertices of the normal form of
1709                      the polygon
1710@*             L[2] : the matrix A of the unimodular transformation
1711@*             L[3] : the translation vector v of the unimodular transformation
1712@*             L[4] : list such that the ith entry is the image of polygon[i]
1713                      under the unimodular transformation T
1714EXAMPLE: example ellipticNF;   shows an example"
1715{
1716  int i;            // index
1717  intvec edge;      // stores the vector of an edge
1718  intvec boundary;  // stores lattice lengths of the edges of the Newton cycle
1719  // find the vertices of the Newton cycle and order it clockwise
1720  list pg=findOrientedBoundary(polygon)[2];
1721  // check if there is precisely one interior point in the Newton polygon
1722  if (picksFormula(pg)[3]!=1)
1723  {
1724    ERROR("The polygon has not precisely one interior point!");
1725  }
1726  // insert the first vertex at the end once again
1727  pg[size(pg)+1]=pg[1];
1728  // compute the number of lattice points on each edge
1729  for (i=1;i<=size(pg)-1;i++)
1730  {
1731    edge=pg[i]-pg[i+1];
1732    boundary[i]=1+abs(gcd(edge[1],edge[2]));
1733  }
1734  // store the values of boundary once more adding the first two at the end
1735  intvec tboundary=boundary,boundary[1],boundary[2];
1736  // sort boundary in an asecending way
1737  intvec sbd=sortintvec(boundary);
1738  // find the first edge having the maximal number of lattice points
1739  int max=maxPosInIntvec(boundary);
1740  // some computations have to be done over the rationals
1741  ring transformationring=0,x,lp;
1742  intvec trans;    // stores the vector by which we have to translate the polygon
1743  intmat A[2][2];  // stores the matrix by which we have to transform the polygon
1744  matrix M[3][3];  // stores the projective coordinates of the points
1745                   // which are to be transformed
1746  matrix N[3][3];  // stores the projective coordinates of the points to
1747                   // which M is to be transformed
1748  intmat T[3][3];  // stores the unimodular affine transformation in
1749                   // projective form
1750  // add the second point of pg once again at the end
1751  pg=insert(pg,pg[2],size(pg));
1752  // if there is only one edge which has the maximal number of lattice points,
1753  // then M should be:
1754  M=pg[max],1,pg[max+1],1,pg[max+2],1;
1755  // consider the 16 different cases which can occur:
1756  // Case 1:
1757  if (sbd==intvec(2,2,2))
1758  {
1759    N=0,1,1,1,2,1,2,0,1;
1760  }
1761  // Case 2:
1762  if (sbd==intvec(2,2,3))
1763  {
1764    N=2,0,1,0,0,1,1,2,1;
1765  }
1766  // Case 3:
1767  if (sbd==intvec(2,3,4))
1768  {
1769    // here the orientation of the Newton polygon is important !
1770    if (tboundary[max+1]==3)
1771    {
1772      N=3,0,1,0,0,1,0,2,1;
1773    }
1774    else
1775    {
1776      N=0,0,1,3,0,1,0,2,1;
1777    }
1778  }
1779  // Case 4:
1780  if (sbd==intvec(3,3,5))
1781  {
1782    N=4,0,1,0,0,1,0,2,1;
1783  }
1784  // Case 5:
1785  if (sbd==intvec(4,4,4))
1786  {
1787    N=3,0,1,0,0,1,0,3,1;
1788  }
1789  // Case 6+7:
1790  if (sbd==intvec(2,2,2,2))
1791  {
1792    // there are two different polygons which has four edges all of length 2,
1793    // but only one of them has two edges whose direction vectors form a matrix
1794    // of determinant 3
1795    A=pg[1]-pg[2],pg[3]-pg[2];
1796    while ((max<4) and (det(A)!=3))
1797    {
1798      max++;
1799      A=pg[max]-pg[max+1],pg[max+2]-pg[max+1];
1800    }
1801    // Case 6:
1802    if (det(A)==3)
1803    {
1804      M=pg[max],1,pg[max+1],1,pg[max+2],1;
1805      N=1,0,1,0,2,1,2,1,1;
1806    }
1807    // Case 7:
1808    else
1809    {
1810      N=2,1,1,1,0,1,0,1,1;
1811    }
1812  }
1813  // Case 8:
1814  if (sbd==intvec(2,2,2,3))
1815  {
1816    // the orientation of the polygon is important
1817    A=pg[max]-pg[max+1],pg[max+2]-pg[max+1];
1818    if (det(A)==2)
1819    {
1820      N=2,0,1,0,0,1,0,1,1;
1821    }
1822    else
1823    {
1824      N=0,0,1,2,0,1,1,2,1;
1825    }
1826  }
1827  // Case 9:
1828  if (sbd==intvec(2,2,3,3))
1829  {
1830    // if max==1, then the 5th entry in tboundary is the same as the first
1831    if (max==1)
1832    {
1833      max=5;
1834    }
1835    // if boundary=3,2,2,3 then set max=4
1836    if (tboundary[max+1]!=3)
1837    {
1838      max=4;
1839    }
1840    M=pg[max],1,pg[max+1],1,pg[max+2],1;
1841    // the orientation of the polygon matters
1842    A=pg[max-1]-pg[max],pg[max+1]-pg[max];   
1843    if (det(A)==4)
1844    {
1845      N=2,0,1,0,0,1,0,2,1;
1846    }
1847    else
1848    {
1849      N=0,2,1,0,0,1,2,0,1;
1850    }
1851  }
1852  // Case 10:
1853  if (sbd==intvec(2,2,3,4))
1854  {
1855    // the orientation of the polygon matters
1856    if (tboundary[max+1]==3)
1857    {
1858      N=3,0,1,0,0,1,0,2,1;
1859    }
1860    else
1861    {
1862      N=0,0,1,3,0,1,2,1,1;
1863    }
1864  }
1865  // Case 11:
1866  if (sbd==intvec(2,3,3,4))
1867  {
1868    N=3,0,1,0,0,1,0,2,1;
1869  }
1870  // Case 12:
1871  if (sbd==intvec(3,3,3,3))
1872  {
1873    N=2,0,1,0,0,1,0,2,1;
1874  }
1875  // Case 13:
1876  if (sbd==intvec(2,2,2,2,2))
1877  {
1878    // compute the angles of the polygon vertices
1879    intvec dt;
1880    for (i=1;i<=5;i++)
1881    {
1882      A=pg[i]-pg[i+1],pg[i+2]-pg[i+1];
1883      dt[i]=det(A);
1884    }
1885    dt[6]=dt[1];
1886    // find the vertex to be mapped to (0,1)
1887    max=1;
1888    while ((dt[max]!=2) or (dt[max+1]!=2))
1889    {
1890      max++;
1891    }   
1892    M=pg[max],1,pg[max+1],1,pg[max+2],1;
1893    N=0,1,1,1,2,1,2,1,1;
1894  }
1895  // Case 14:
1896  if (sbd==intvec(2,2,2,2,3))
1897  {
1898    N=2,0,1,0,0,1,0,1,1;
1899  }
1900  // Case 15:
1901  if (sbd==intvec(2,2,2,3,3))
1902  {
1903    // find the vertix to be mapped to (2,0)
1904    if (tboundary[max+1]!=3)
1905    {
1906      max=5;
1907      M=pg[max],1,pg[max+1],1,pg[max+2],1;
1908    }
1909    N=2,0,1,0,0,1,0,2,1;
1910  }
1911  // Case 16:
1912  if (sbd==intvec(2,2,2,2,2,2))
1913  {
1914    N=2,0,1,1,0,1,0,1,1;
1915  }
1916  // we have to transpose the matrices M and N
1917  M=transpose(M);
1918  N=transpose(N);
1919  // compute the unimodular affine transformation, which is of the form
1920  // A11 A12 | T1
1921  // A21 A22 | T2
1922  //  0   0  | 1
1923  T=matrixtointmat(N*inverse(M));
1924  // the upper-left 2x2-block is A
1925  A=T[1..2,1..2];
1926  // the upper-right 2x1-block is the translation vector
1927  trans=T[1,3],T[2,3];
1928  // transform now the lattice points of the polygon with respect to A and T
1929  list nf;
1930  for (i=1;i<=size(polygon);i++)
1931  {
1932    intmat V[2][1]=polygon[i];
1933    V=A*V;
1934    nf[i]=intvec(V[1,1]+trans[1],V[2,1]+trans[2]);
1935    kill V;
1936  }
1937  return(list(findOrientedBoundary(nf)[2],A,trans,nf));
1938}
1939example
1940{
1941   "EXAMPLE:";
1942   echo=2;
1943   ring r=0,(x,y),dp;
1944   // the Newton polygon of the following polynomial
1945   //     has precisely one interior point
1946   poly f=x22y11+x19y10+x17y9+x16y9+x12y7+x9y6+x7y5+x2y3;
1947   list polygon=newtonPolytopeLP(f);
1948   // its lattice points are
1949   polygon;
1950   // find its normal form
1951   list nf=ellipticNF(polygon);
1952   // the vertices of the normal form are
1953   nf[1];
1954   // it has been transformed by the unimodular affine transformation A*x+v
1955   // with matrix A
1956   nf[2];
1957   // and translation vector v
1958   nf[3];
1959   // the 3rd lattice point ...
1960   polygon[3];
1961   // ... has been transformed to
1962   nf[4][3];
1963}
1964
1965
1966/////////////////////////////////////////////////////////////////////////////
1967
1968proc ellipticNFDB (int n,list #)
1969"USAGE:  ellipticNFDB(n[,#]);   n int, # list
1970ASSUME:  n is an integer between 1 and 16
1971PURPOSE: this is a database storing the 16 normal forms of planar polygons with
1972         precisely one interior point up to unimodular affine transformations
1973@*       (see e.g. Bjorn Poonen, Fernando Rodriguez-Villegas: Lattice Polygons
1974                   and the number 12.  Amer. Math. Monthly  107  (2000),  no. 3,
1975                   238--250.)
1976RETURN:  list, L such that
1977@*             L[1] : list whose entries are the vertices of the nth normal form
1978@*             L[2] : list whose entries are all the lattice points of the
1979                      nth normal form
1980@*             L[3] : only present if the optional parameter # is present, and
1981                      then it is a polynomial in the variables (x,y) whose
1982                      Newton polygon is the nth normal form
1983NOTE:    the optional parameter is only allowed if the basering has the
1984         variables x and y
1985EXAMPLE: example ellipticNFDB;   shows an example"
1986{
1987  if ((n<1) or (n>16))
1988  {
1989    ERROR("n is not between 1 and 16.");
1990  }
1991  if (size(#)>0)
1992  {
1993    if ((defined(x)==0) or (defined(y)==0))
1994    {
1995      ERROR("The variables x and y are not defined.");
1996    }
1997  }
1998  if ((defined(x)==0) or (defined(y)==0))
1999  {
2000    ring nfring=0,(x,y),dp;
2001  }
2002  // store the normal forms as polynomials
2003  list nf=x2+y+xy2,x2+x+1+xy2,x3+x2+x+1+y2+y,x4+x3+x2+x+1+y2+y+x2y,x3+x2+x+1+x2y+y+xy2+y2+y3,
2004    x2+x+x2y+y2,x2y+x+y+xy2,x2+x+1+y+xy2,x2+x+1+y+xy2+y2,x3+x2+x+1+x2y+y+y2,x3+x2+x+1+x2y+y+xy2+y2,
2005    x2+x+1+x2y+y+x2y2+xy2+y2,x+1+x2y+y+xy2,x2+x+1+x2y+y+xy2,x2+x+1+x2y+y+xy2+y2,x2+x+x2y+y+xy2+y2;
2006  list pg=newtonPolytopeLP(nf[n]);
2007  if (size(#)==0)
2008  {
2009    return(list(findOrientedBoundary(pg)[2],pg));
2010  }
2011  else
2012  {
2013    return(list(findOrientedBoundary(pg)[2],pg,nf[n]));
2014  }
2015}
2016example
2017{
2018   "EXAMPLE:";
2019   echo=2;
2020   list nf=ellipticNFDB(5);
2021   // the vertices of the 5th normal form are
2022   nf[1];
2023   // its lattice points are
2024   nf[2];
2025}
2026
2027
2028/////////////////////////////////////////////////////////////////////////////////
2029/////////////////////////////////////////////////////////////////////////////////
2030/// AUXILARY PROCEDURES, WHICH ARE DECLARED STATIC
2031/////////////////////////////////////////////////////////////////////////////////
2032/////////////////////////////////////////////////////////////////////////////////
2033/// - scalarproduct
2034/// - intmatcoldelete
2035/// - intmatconcat
2036/// - sortlist
2037/// - minInList
2038/// - stringdelete
2039/// - abs
2040/// - commondenominator
2041/// - maxPosInIntvec
2042/// - maxPosInIntmat
2043/// - sortintvec
2044/// - matrixtointmat
2045/////////////////////////////////////////////////////////////////////////////////
2046
2047static proc scalarproduct (intvec w,intvec v)
2048"USAGE:      scalarproduct(w,v); w,v intvec
2049ASSUME:      w and v are integer vectors of the same length
2050RETURN:      int, the scalarproduct of v and w
2051NOTE:        the procedure is called by findOrientedBoundary"
2052{
2053  int sp;
2054  for (int i=1;i<=size(w);i++)
2055  {
2056    sp=sp+v[i]*w[i];
2057  }
2058  return(sp);
2059}
2060
2061static proc intmatcoldelete (intmat w,int i)
2062"USAGE:      intmatcoldelete(w,i); w intmat, i int
2063RETURN:      intmat, the integer matrix w with the ith comlumn deleted
2064NOTE:        the procedure is called by intmatsort and normalFan"
2065{
2066  if ((i<1) or (i>ncols(w)) or (ncols(w)==1))
2067  {
2068    return(w);
2069  }
2070  if (i==1)
2071  {
2072    intmat M[nrows(w)][ncols(w)-1]=w[1..nrows(w),2..ncols(w)];
2073    return(M);
2074  }
2075  if (i==ncols(w))
2076  {
2077    intmat M[nrows(w)][ncols(w)-1]=w[1..nrows(w),1..ncols(w)-1];
2078    return(M);
2079  }
2080  else
2081  {
2082    intmat M[nrows(w)][i-1]=w[1..nrows(w),1..i-1];
2083    intmat N[nrows(w)][ncols(w)-i]=w[1..nrows(w),i+1..ncols(w)];
2084    return(intmatconcat(M,N));
2085  }
2086}
2087
2088static proc intmatconcat (intmat M,intmat N)
2089"USAGE:      intmatconcat(M,N); M,N intmat
2090RETURN:      intmat, M and N concatenated
2091NOTE:        the procedure is called by intmatcoldelete and sortintmat"
2092{
2093  if (nrows(M)>=nrows(N))
2094  {
2095    int m=nrows(M);
2096   
2097  }
2098  else
2099  {
2100    int m=nrows(N);
2101  }
2102  intmat P[m][ncols(M)+ncols(N)];
2103  P[1..nrows(M),1..ncols(M)]=M[1..nrows(M),1..ncols(M)];
2104  P[1..nrows(N),ncols(M)+1..ncols(M)+ncols(N)]=N[1..nrows(N),1..ncols(N)];
2105  return(P);
2106}
2107
2108static proc sortlist (list v,int pos)
2109"USAGE:      sortlist(v,pos); v list, pos int
2110RETURN:      list, the list L ordered in an ascending way according to the pos-th entries
2111NOTE:        called by tropicalCurve"
2112{
2113  if(size(v)==1)
2114  {
2115    return(v);
2116  }
2117  list w=minInList(v,pos);
2118  v=delete(v,w[2]);
2119  v=sortlist(v,pos);
2120  v=list(w[1])+v;
2121  return(v);
2122}
2123
2124static proc minInList (list v,int pos)
2125"USAGE:      minInList(v,pos); v list, pos int
2126RETURN:      list, (v[i],i) such that v[i][pos] is minimal
2127NOTE:        called by sortlist"
2128{
2129  int min=v[1][pos];
2130  int minpos=1;
2131  for (int i=2;i<=size(v);i++)
2132  {
2133    if (v[i][pos]<min)
2134    {
2135      min=v[i][pos];
2136      minpos=i;
2137    }
2138  }
2139  return(list(v[minpos],minpos));
2140}
2141
2142static proc stringdelete (string w,int i)
2143"USAGE:      stringdelete(w,i); w string, i int
2144RETURN:      string, the string w with the ith component deleted
2145NOTE:        the procedure is called by texnumber and choosegfanvector"
2146{
2147  if ((i>size(w)) or (i<=0))
2148  {
2149    return(w);
2150  }
2151  if ((size(w)==1) and (i==1))
2152  {
2153    return("");
2154   
2155  }
2156  if (i==1)
2157  {
2158    return(w[2..size(w)]);
2159  }
2160  if (i==size(w))
2161  {
2162    return(w[1..size(w)-1]);
2163  }
2164  else
2165  {
2166    string erg=w[1..i-1],w[i+1..size(w)];
2167    return(erg);
2168  }
2169}
2170
2171static proc abs (def n)
2172"USAGE:      abs(n); n poly or int
2173RETURN:      poly or int, the absolute value of n"
2174{
2175  if (n>=0)
2176  {
2177    return(n);
2178  }
2179  else
2180  {
2181    return(-n);
2182  }
2183}
2184
2185static proc commondenominator (matrix M)
2186"USAGE:   commondenominator(M);  M matrix
2187ASSUME:   the base ring has characteristic zero
2188RETURN:   int, the lowest common multiple of the denominators of the leading coefficients
2189               of the entries in M
2190NOTE:        the procedure is called from polymakeToIntmat"
2191{
2192  int i,j;
2193  int kgV=1;
2194  // successively build the lowest common multiple of the denominators of the leading coefficients
2195  // of the entries in M
2196  for (i=1;i<=nrows(M);i++)
2197  {
2198    for (j=1;j<=ncols(M);j++)
2199    {
2200      kgV=lcm(kgV,int(denominator(leadcoef(M[i,j]))));
2201    }
2202  }
2203  return(kgV);
2204}
2205
2206static proc maxPosInIntvec (intvec v)
2207"USAGE:      maxPosInIntvec(v); v intvec
2208RETURN:      int, the first position of a maximal entry in v
2209NOTE:        called by sortintmat"
2210{
2211  int max=v[1];
2212  int maxpos=1;
2213  for (int i=2;i<=size(v);i++)
2214  {
2215    if (v[i]>max)
2216    {
2217      max=v[i];
2218      maxpos=i;
2219    }
2220  }
2221  return(maxpos);
2222}
2223
2224static proc maxPosInIntmat (intmat v)
2225"USAGE:      maxPosInIntmat(v); v intmat
2226ASSUME:      v has a unique maximal entry
2227RETURN:      intvec, the position (i,j) of the maximal entry in v
2228NOTE:        called by findOrientedBoundary"
2229{
2230  int max=v[1,1];
2231  intvec maxpos=1,1;
2232  int i,j;
2233  for (i=1;i<=nrows(v);i++)
2234  {
2235    for (j=1;j<=ncols(v);j++)
2236    {
2237      if (v[i,j]>max)
2238      {
2239        max=v[i,j];
2240        maxpos=i,j;
2241      }
2242    }
2243  }
2244  return(maxpos);
2245}
2246
2247static proc sortintvec (intvec w)
2248"USAGE:      sortintvec(v); v intvec
2249RETURN:      intvec, the entries of v are ordered in an ascending way
2250NOTE:        called from ellipticNF"
2251{
2252  int j,k,stop;
2253  intvec v=w[1];
2254  for (j=2;j<=size(w);j++)
2255  {
2256    k=1;
2257    stop=0;
2258    while ((k<=size(v)) and (stop==0))
2259    {
2260      if (v[k]<w[j])
2261      {
2262        k++;
2263      }
2264      else
2265      {
2266        stop=1;
2267      }
2268    }
2269    if (k==size(v)+1)
2270    {
2271      v=v,w[j];
2272    }
2273    else
2274    {
2275      if (k==1)
2276      {
2277        v=w[j],v;
2278      }
2279      else
2280      {
2281        v=v[1..k-1],w[j],v[k..size(v)];
2282      }
2283    }
2284  }
2285  return(v);
2286}
2287
2288static proc sortlistbyintvec (list L,intvec w)
2289"USAGE:      sortlistbyintvec(L,w); L list, w intvec
2290RETURN:      list, the entries of L are ordered such that the corresponding reordering of
2291                   w would order w in an ascending way
2292NOTE:        called from ellipticNF"
2293{
2294  int j,k,stop;
2295  intvec v=w[1];
2296  list LL=L[1];
2297  for (j=2;j<=size(w);j++)
2298  {
2299    k=1;
2300    stop=0;
2301    while ((k<=size(v)) and (stop==0))
2302    {
2303      if (v[k]<w[j])
2304      {
2305        k++;
2306      }
2307      else
2308      {
2309        stop=1;
2310      }
2311    }
2312    if (k==size(v)+1)
2313    {
2314      v=v,w[j];
2315      LL=insert(LL,L[j],size(LL));
2316    }
2317    else
2318    {
2319      if (k==1)
2320      {
2321        v=w[j],v;
2322        LL=insert(LL,L[j]);
2323      }
2324      else
2325      {
2326        v=v[1..k-1],w[j],v[k..size(v)];
2327        LL=insert(LL,L[j],k-1);
2328      }
2329    }
2330  }
2331  return(LL);
2332}
2333
2334static proc matrixtointmat (matrix MM)
2335"USAGE:      matrixtointmat(v); MM matrix
2336ASSUME:      MM is a matrix with only integers as entries
2337RETURN:      intmat, the matrix MM has been transformed to type intmat
2338NOTE:        called from ellipticNF"
2339{
2340  intmat M[nrows(MM)][ncols(MM)]=M;
2341  int i,j;
2342  for (i=1;i<=nrows(M);i++)
2343  {
2344    for (j=1;j<=ncols(M);j++)
2345    {
2346      execute("M["+string(i)+","+string(j)+"]="+string(MM[i,j])+";");
2347    }
2348  }
2349  return(M);
2350}
2351
2352//////////////////////////////////////////////////////////////////////////////
2353
2354static proc polygonToCoordinates (list points)
2355"USAGE:      polygonToCoordinates(points);   points list
2356ASSUME:      points is a list of integer vectors each of size two describing the
2357             marked points of a convex lattice polygon like the output of
2358             polygonDB
2359RETURN:      list, the first entry is a string representing the coordinates
2360                   corresponding to the latticpoints seperated by commata
2361                   the second entry is a list where the ith entry is a string
2362                   representing the coordinate of corresponding to the ith
2363                   lattice point the third entry is the latex format of the
2364                   first entry
2365NOTE:        the procedure is called by fan"
2366{
2367  string coord;
2368  list coords;
2369  string latex;
2370  for (int i=1;i<=size(points);i++)
2371  {
2372    coords[i]="u"+string(points[i][1])+string(points[i][2]);
2373    coord=coord+coords[i]+",";
2374    latex=latex+"u_{"+string(points[i][1])+string(points[i][2])+"},";
2375  }
2376  coord=coord[1,size(coord)-1];
2377  latex=latex[1,size(latex)-1];
2378  return(list(coord,coords,latex));
2379}
2380
2381static proc intmatAddFirstColumn (intmat M,string art)
2382"USAGE:  intmatAddFirstColumn(M,art);  M intmat, art string
2383ASSUME:  - M is an integer matrix where a first column of 0's or 1's should be added
2384@*       - art is one of the following strings:
2385@*         + 'rays'   : indicating that a first column of 0's should be added
2386@*         + 'points' : indicating that a first column of 1's should be added
2387RETURN:  intmat, a first column has been added to the matrix"
2388{
2389  intmat N[nrows(M)][ncols(M)+1];
2390  int i,j;
2391  for (i=1;i<=nrows(M);i++)
2392  {
2393    if (art=="rays")
2394    {
2395      N[i,1]=0;
2396    }
2397    else
2398    {
2399      N[i,1]=1;
2400    }
2401    for (j=1;j<=ncols(M);j++)
2402    {
2403      N[i,j+1]=M[i,j];
2404    }
2405  }
2406  return(N);
2407}
2408
2409
2410
Note: See TracBrowser for help on using the repository browser.