3
#include "polynomial.h"
5
#include "buchberger.h"
8
#include "reversesearch.h"
9
#include "breadthfirstsearch.h"
10
#include "termorder.h"
11
#include "ep_standard.h"
13
#include "gfanapplication.h"
18
#include "polyhedralfan.h"
20
#include "determinant.h"
21
#include "triangulation.h"
22
#include "intsinpolytope.h"
25
#include "triangulation2.h"
27
#include "traverser_secondaryfan.h"
28
#include "symmetrictraversal.h"
33
class SecondaryFanApplication : public GFanApplication
35
SimpleOption hirschOption;
36
SimpleOption searchOption;
37
IntegerOption scaleOption;
38
StringOption optionRestrictingFan;
39
SimpleOption symmetryOption;
40
SimpleOption optionIgnoreCones;
42
const char *helpText()
44
return "This program computes the secondary fan of a vector configuration. The configuration is given as an ordered list of vectors. In order to compute the secondary fan of a point configuration an additional coordinate of ones must be added. For example {(1,0),(1,1),(1,2),(1,3)}.\n";
46
SecondaryFanApplication():
47
searchOption("--unimodular","Use heuristics to search for unimodular triangulation rather than computing the complete secondary fan"),
48
scaleOption("--scale","Assuming that the first coordinate of each vector is 1, this option will take the polytope in the 1 plane and scale it. The point configuration will be all lattice points in that scaled polytope. The polytope must have maximal dimension. When this option is used the vector configuration must have full rank. This option may be removed in the future."),
49
symmetryOption("--symmetry","Tells the program to read in generators for a group of symmetries (subgroup of $S_n$) after having read in the vector configuration. The program checks that the configuration stays fixed when permuting the variables with respect to elements in the group. The output is grouped according to the symmetry.\n"),
50
optionRestrictingFan("--restrictingfan","Specify the name of a file containing a polyhedral fan in Polymake format. The computation of the Secondary fan will be restricted to this fan. If the --symmetry option is used then this restricting fan must be invariant under the symmetry and the orbits in the file must be with respect to the specified group of symmetries. The orbits of maximal cones of the file are then read in rather than the maximal cones.\n",0),
51
optionIgnoreCones("--nocones","Tells the program not to output the CONES and MAXIMAL_CONES sections, but still output CONES_COMPRESSED and MAXIMAL_CONES_COMPRESSED if --symmetry is used."),
52
hirschOption("--hirsch","")
60
return "_secondaryfan";
63
PolyhedralFan enumerate(Triangulation2 const &t)
65
PolyhedralFan ret(t.getN());
66
list<Triangulation2> active;
68
IntegerVectorList interiorPoints;
69
interiorPoints.push_back(t.interiorPoint());
70
while(!active.empty())
72
Triangulation2 a=active.front();
73
PolyhedralCone C=a.secondaryCone();
76
// if(active.size()>100)break;//SLETMIGGGGG
77
//log0 fprintf(stderr,"a\n");
83
//log0 fprintf(stderr,"b\n");
85
AsciiPrinter P(Stderr);
88
// fprintf(stderr,"pop\n");
89
IntegerVectorList flips=a.facets();
90
for(IntegerVectorList::const_iterator i=flips.begin();i!=flips.end();i++)
93
IntegerVectorList t=C.getEquations();
95
PolyhedralCone CF(C.getHalfSpaces(),t);
100
if(!i->isNonNegative()) //is this the right condition or should i be negated?
101
// if(!(-*i).isNonNegative()) //is this the right condition or should i be negated?
104
log1 AsciiPrinter(Stderr)<<*i;
105
/*fprintf(stderr,"Before:");
109
/*fprintf(stderr,"After:");
113
IntegerVectorList inequalities=b.inequalities();
115
for(IntegerVectorList::const_iterator j=interiorPoints.begin();j!=interiorPoints.end();j++)
118
for(IntegerVectorList::const_iterator k=inequalities.begin();k!=inequalities.end();k++)
120
if(dotLong(-*k,*j)<0)
126
if(match)isKnown=true;
131
interiorPoints.push_back(b.interiorPoint());
139
PolyhedralFan interactive(Triangulation2 const &t)
145
fprintf(stdout,"Triangles in current triangulation:%i\n",a.bases.size());
146
PolyhedralCone C=a.secondaryCone();
151
AsciiPrinter Pstd(Stderr);
152
IntegerVectorList flips=a.facets();
154
for(IntegerVectorList::const_iterator i=flips.begin();i!=flips.end();i++,I++)
156
fprintf(stdout,"%i:\n",I);
157
Pstd.printVector(*i);
160
if(!i->isNonNegative())
163
//fprintf(stderr,"Before:");
167
//fprintf(stderr,"After:");
169
fprintf(stdout,"Triangles in new triangulation:%i\n",b.bases.size());
173
fprintf(stdout,"\n");
177
fscanf(stdin,"%i",&s);
180
IntegerVectorList::const_iterator i=flips.begin();
181
for(int I=0;I<s;I++)i++;
189
PolyhedralFan ret(0);
193
PolyhedralFan automatic(Triangulation2 const &t, int abortAtSize)
197
cout << "Looking for triangulation with "<<abortAtSize<<" simplices."<<endl;
201
fprintf(stdout,"Triangles in current triangulation:%i\n",a.bases.size());
202
// PolyhedralCone C=a.secondaryCone();
207
AsciiPrinter Pstd(Stderr);
208
IntegerVectorList flips=a.facets();
210
cerr << "Number of facets of secondary cone: " << flips.size() <<endl;
211
for(IntegerVectorList::const_iterator i=flips.begin();i!=flips.end();i++,I++)
213
if(!i->isNonNegative())
217
fprintf(stdout,"Triangles in new triangulation:%i\n",b.bases.size());
219
if(b.bases.size()==abortAtSize)
226
if((b.bases.size()>a.bases.size())||((rand()&127)==0))
234
PolyhedralFan ret(0);
238
PolyhedralFan automaticHirsch(Triangulation2 const &t)
243
int nVertices=a.bases.size();
244
int nEdges=a.coDimensionOneTriangles().size();
245
int diameter=a.edgeGraph().diameter();
246
int dimension=a.getD();
247
int nFacets=a.usedRays().size();
248
fprintf(stdout,"NVER: %i NEDGES: %i DIAMETER:%i DIMENSION:%i NFACETS:%i\n",nVertices,nEdges,diameter,dimension,nFacets);
250
AsciiPrinter Pstd(Stderr);
251
IntegerVectorList flips=a.facets();
253
float currentScore=a.hirschScore();
254
cerr << "Current score: " << currentScore <<endl;
255
for(IntegerVectorList::const_iterator i=flips.begin();i!=flips.end();i++,I++)
257
if(!i->isNonNegative())
261
float bScore=b.hirschScore();
262
fprintf(stdout,"New score:%f\n",bScore);
264
if((bScore>currentScore)||((rand()&31)==0))
272
PolyhedralFan ret(0);
278
IntegerMatrix A=rowsToIntegerMatrix(FileParser(Stdin).parseIntegerVectorList()).transposed();
283
if(symmetryOption.getValue())
285
IntegerVectorList generators=FileParser(Stdin).parseIntegerVectorList();
286
for(IntegerVectorList::const_iterator i=generators.begin();i!=generators.end();i++)
288
assert(i->size()==n);
289
FieldMatrix M1=integerMatrixToFieldMatrix(A,Q);
290
FieldMatrix M2=integerMatrixToFieldMatrix(rowsToIntegerMatrix(SymmetryGroup::permuteIntegerVectorList(A.getRows(),*i)),Q);
292
M1.REformToRREform(true);
294
M2.REformToRREform(true);
298
AsciiPrinter(Stderr) << "Permutation "<< *i <<
299
" does not keep the configuration fixed.\n";
303
s.computeClosure(generators);
308
if(scaleOption.getValue())
310
if(rank(A)!=A.getHeight())
312
cerr << "The vector configuration must have full rank in order to use the scale option.\n";
316
int s=scaleOption.getValue();
318
cout << "Input configuration:" << endl;
319
AsciiPrinter(Stdout)<<A.transposed().getRows();
321
IntegerVectorList empty;
322
PolyhedralCone dual(A.transposed().getRows(),empty,n);
324
assert(dual.dimensionOfLinealitySpace()==0);
325
IntegerVectorList inequalities=dual.extremeRays();
327
IntegerMatrix M1=rowsToIntegerMatrix(inequalities);
328
IntegerMatrix M2=-1*M1.submatrix(0,1,M1.getHeight(),M1.getWidth());
329
IntegerVector rightHandSide=s*M1.transposed().submatrix(0,0,1,M1.getWidth())[0];
330
IntegerVector v=s*A.submatrix(1,0,A.getHeight(),1).transposed()[0];
332
IntegerVectorList l=intsInPolytopeGivenIneqAndPt(M2,rightHandSide,v);
334
IntegerVectorList lT=rowsToIntegerMatrix(l).transposed().getRows();
335
lT.push_front(IntegerVector::allOnes(l.size()));
336
l=rowsToIntegerMatrix(lT).transposed().getRows();
338
cout << "New configuration:" << endl;
339
AsciiPrinter(Stdout)<<l;
340
A=rowsToIntegerMatrix(l).transposed();
343
/* If the vector configuration A does not have full rank then
344
change coordinates. */
345
if(rank(A)!=A.getHeight())
347
FieldMatrix M=integerMatrixToFieldMatrix(A,Q);
348
M.reduce(false,true);//force integer operations - preserving volume
350
A=fieldMatrixToIntegerMatrix(M);
356
/* Convert a Triangulation to a Triangulation2 */
358
list<Triangulation::Cone> T=Triangulation::triangulate(A.transposed());
359
for(list<Triangulation::Cone>::const_iterator i=T.begin();i!=T.end();i++)
361
IntegerVector v=i->size();
363
for(Triangulation::Cone::const_iterator j=i->begin();j!=i->end();j++,J++)
369
if(searchOption.getValue())
371
PolyhedralFan f=automatic(t,t.totalVolume());
373
else if(hirschOption.getValue())
375
PolyhedralFan f=automaticHirsch(t);
379
SymmetricTargetFanBuilder target(n,s);
381
if(!optionRestrictingFan.getValue())
383
SecondaryFanTraverser traverser(t);
384
symmetricTraverse(traverser,target,&s);
388
PolyhedralFan f1=PolyhedralFan::readFan(optionRestrictingFan.getValue(),true,0,0,/*optionSymmetry.getValue()?&s:0*/0,false/*true*/);
390
for(PolyhedralFan::coneIterator i=f1.conesBegin();i!=f1.conesEnd();i++)
393
log2 cerr<<"Processing Cone "<<a++<<" which has dimension "<<i->dimension()<<endl;
394
SecondaryFanTraverser traverser(triangulationWithFullDimensionalIntersection(t,*i),*i);
395
symmetricTraverse(traverser,target,&s);
399
target.getFanRef().printWithIndices(&pout,
400
(symmetryOption.getValue()?FPF_group|FPF_conesCompressed:0)|
401
(optionIgnoreCones.getValue()?0:FPF_conesExpanded)|
402
FPF_maximalCones|FPF_cones,
404
/* target.getFanRef().printWithIndices(&p,
406
(symmetryOption.getValue()?FPF_group|FPF_conesCompressed:0),
409
/* PolyhedralFan f=enumerate(t).negated();//Changing sign
411
f.printWithIndices(&p,
413
(symmetryOption.getValue()?FPF_group|FPF_conesCompressed:0),
421
static SecondaryFanApplication theApplication;