~ubuntu-branches/ubuntu/saucy/gfan/saucy-proposed

« back to all changes in this revision

Viewing changes to app_secondaryfan.cpp

  • Committer: Package Import Robot
  • Author(s): Cédric Boutillier
  • Date: 2013-07-09 10:44:01 UTC
  • mfrom: (2.1.2 experimental)
  • Revision ID: package-import@ubuntu.com-20130709104401-5q66ozz5j5af0dak
Tags: 0.5+dfsg-3
* Upload to unstable.
* modify remove_failing_tests_on_32bits.patch to replace command of
  0009RenderStairCase test with an empty one instead of deleting it.
* remove lintian override about spelling error

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "parser.h"
 
2
#include "printer.h"
 
3
#include "polynomial.h"
 
4
#include "division.h"
 
5
#include "buchberger.h"
 
6
#include "wallideal.h"
 
7
#include "lp.h"
 
8
#include "reversesearch.h"
 
9
#include "breadthfirstsearch.h"
 
10
#include "termorder.h"
 
11
#include "ep_standard.h"
 
12
#include "ep_xfig.h"
 
13
#include "gfanapplication.h"
 
14
#include "timer.h"
 
15
#include "log.h"
 
16
#include "matrix.h"
 
17
#include "lll.h"
 
18
#include "polyhedralfan.h"
 
19
#include "linalg.h"
 
20
#include "determinant.h"
 
21
#include "triangulation.h"
 
22
#include "intsinpolytope.h"
 
23
#include "graph.h"
 
24
 
 
25
#include "triangulation2.h"
 
26
 
 
27
#include "traverser_secondaryfan.h"
 
28
#include "symmetrictraversal.h"
 
29
 
 
30
#include <iostream>
 
31
#include <algorithm>
 
32
 
 
33
class SecondaryFanApplication : public GFanApplication
 
34
{
 
35
  SimpleOption hirschOption;
 
36
  SimpleOption searchOption;
 
37
  IntegerOption scaleOption;
 
38
  StringOption optionRestrictingFan;
 
39
  SimpleOption symmetryOption;
 
40
  SimpleOption optionIgnoreCones;
 
41
public:
 
42
  const char *helpText()
 
43
  {
 
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";
 
45
  }
 
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","")
 
53
  {
 
54
    hirschOption.hide();
 
55
    registerOptions();
 
56
  }
 
57
 
 
58
  const char *name()
 
59
  {
 
60
    return "_secondaryfan";
 
61
  }
 
62
 
 
63
  PolyhedralFan enumerate(Triangulation2 const &t)
 
64
  {
 
65
    PolyhedralFan ret(t.getN());
 
66
    list<Triangulation2> active;
 
67
    active.push_back(t);
 
68
    IntegerVectorList interiorPoints;
 
69
    interiorPoints.push_back(t.interiorPoint());
 
70
    while(!active.empty())
 
71
      {
 
72
        Triangulation2 a=active.front();
 
73
        PolyhedralCone C=a.secondaryCone();
 
74
 
 
75
 
 
76
        //      if(active.size()>100)break;//SLETMIGGGGG
 
77
        //log0 fprintf(stderr,"a\n");
 
78
        /*      {
 
79
          PolyhedralCone C2=C;
 
80
          C2.canonicalize();
 
81
          }*/
 
82
        C.canonicalize();
 
83
        //log0 fprintf(stderr,"b\n");
 
84
        ret.insert(C);
 
85
        AsciiPrinter P(Stderr);
 
86
        //      C.print(&P);
 
87
        active.pop_front();
 
88
        //      fprintf(stderr,"pop\n");
 
89
        IntegerVectorList flips=a.facets();
 
90
        for(IntegerVectorList::const_iterator i=flips.begin();i!=flips.end();i++)
 
91
          {
 
92
            {
 
93
              IntegerVectorList t=C.getEquations();
 
94
              t.push_back(*i);
 
95
              PolyhedralCone CF(C.getHalfSpaces(),t);
 
96
              CF.findFacets();
 
97
              //              CF.canonicalize();
 
98
            }
 
99
 
 
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?
 
102
              {
 
103
                Triangulation2 b=a;
 
104
                log1 AsciiPrinter(Stderr)<<*i;
 
105
                /*fprintf(stderr,"Before:");
 
106
                  b.print(P);*/
 
107
                //              b.flip(*i);
 
108
                b.flipNew(-*i);
 
109
                /*fprintf(stderr,"After:");
 
110
                  b.print(P);*/
 
111
                if(!b.isEmpty())
 
112
                  {
 
113
                    IntegerVectorList inequalities=b.inequalities();
 
114
                    bool isKnown=false;
 
115
                    for(IntegerVectorList::const_iterator j=interiorPoints.begin();j!=interiorPoints.end();j++)
 
116
                      {
 
117
                        bool match=true;
 
118
                        for(IntegerVectorList::const_iterator k=inequalities.begin();k!=inequalities.end();k++)
 
119
                          {
 
120
                            if(dotLong(-*k,*j)<0)
 
121
                              {
 
122
                                match=false;
 
123
                                break;
 
124
                              }
 
125
                          }
 
126
                        if(match)isKnown=true;
 
127
                      }
 
128
                    if(!isKnown)
 
129
                      {
 
130
                        active.push_back(b);
 
131
                        interiorPoints.push_back(b.interiorPoint());
 
132
                      }
 
133
                  }
 
134
              }
 
135
          }
 
136
      }
 
137
    return ret;
 
138
  }
 
139
  PolyhedralFan interactive(Triangulation2 const &t)
 
140
  {
 
141
    Triangulation2 a=t;
 
142
 
 
143
    while(1)
 
144
      {
 
145
        fprintf(stdout,"Triangles in current triangulation:%i\n",a.bases.size());
 
146
        PolyhedralCone C=a.secondaryCone();
 
147
 
 
148
        C.canonicalize();
 
149
 
 
150
 
 
151
        AsciiPrinter Pstd(Stderr);
 
152
        IntegerVectorList flips=a.facets();
 
153
        int I=0;
 
154
        for(IntegerVectorList::const_iterator i=flips.begin();i!=flips.end();i++,I++)
 
155
          {
 
156
            fprintf(stdout,"%i:\n",I);
 
157
            Pstd.printVector(*i);
 
158
 
 
159
 
 
160
            if(!i->isNonNegative())
 
161
              {
 
162
                Triangulation2 b=a;
 
163
                //fprintf(stderr,"Before:");
 
164
                //b.print(P);
 
165
                //              b.flip(*i);
 
166
                /*              b.flipNew(*i);
 
167
                //fprintf(stderr,"After:");
 
168
                //b.print(P);
 
169
                fprintf(stdout,"Triangles in new triangulation:%i\n",b.bases.size());
 
170
                */
 
171
              }
 
172
 
 
173
            fprintf(stdout,"\n");
 
174
          }
 
175
        int s;
 
176
        //cin >> s;
 
177
        fscanf(stdin,"%i",&s);
 
178
        if((s>=0)&&(s<I))
 
179
          {
 
180
            IntegerVectorList::const_iterator i=flips.begin();
 
181
            for(int I=0;I<s;I++)i++;
 
182
            a.flipNew(*i);
 
183
          }
 
184
        else
 
185
          {
 
186
            a.print(Pstd);
 
187
          }
 
188
      }
 
189
    PolyhedralFan ret(0);
 
190
 
 
191
    return ret;
 
192
  }
 
193
  PolyhedralFan automatic(Triangulation2 const &t, int abortAtSize)
 
194
  {
 
195
    Triangulation2 a=t;
 
196
 
 
197
    cout << "Looking for triangulation with "<<abortAtSize<<" simplices."<<endl;
 
198
 
 
199
    while(1)
 
200
      {
 
201
        fprintf(stdout,"Triangles in current triangulation:%i\n",a.bases.size());
 
202
        //      PolyhedralCone C=a.secondaryCone();
 
203
 
 
204
        //      C.canonicalize();
 
205
 
 
206
 
 
207
        AsciiPrinter Pstd(Stderr);
 
208
        IntegerVectorList flips=a.facets();
 
209
        int I=0;
 
210
        cerr << "Number of facets of secondary cone: " << flips.size() <<endl;
 
211
        for(IntegerVectorList::const_iterator i=flips.begin();i!=flips.end();i++,I++)
 
212
          {
 
213
            if(!i->isNonNegative())
 
214
              {
 
215
                Triangulation2 b=a;
 
216
                b.flipNew(-*i);
 
217
                fprintf(stdout,"Triangles in new triangulation:%i\n",b.bases.size());
 
218
 
 
219
                if(b.bases.size()==abortAtSize)
 
220
                  {
 
221
                    b.print(Pstd);
 
222
 
 
223
                    exit(0);
 
224
                  }
 
225
 
 
226
                if((b.bases.size()>a.bases.size())||((rand()&127)==0))
 
227
                  {
 
228
                    a=b;
 
229
                    break;
 
230
                  }
 
231
              }
 
232
          }
 
233
      }
 
234
    PolyhedralFan ret(0);
 
235
 
 
236
    return ret;
 
237
  }
 
238
  PolyhedralFan automaticHirsch(Triangulation2 const &t)
 
239
  {
 
240
    Triangulation2 a=t;
 
241
    while(1)
 
242
      {
 
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);
 
249
 
 
250
        AsciiPrinter Pstd(Stderr);
 
251
        IntegerVectorList flips=a.facets();
 
252
        int I=0;
 
253
        float currentScore=a.hirschScore();
 
254
        cerr << "Current score: " << currentScore <<endl;
 
255
        for(IntegerVectorList::const_iterator i=flips.begin();i!=flips.end();i++,I++)
 
256
          {
 
257
            if(!i->isNonNegative())
 
258
              {
 
259
                Triangulation2 b=a;
 
260
                b.flipNew(-*i);
 
261
                float bScore=b.hirschScore();
 
262
                fprintf(stdout,"New score:%f\n",bScore);
 
263
 
 
264
                if((bScore>currentScore)||((rand()&31)==0))
 
265
                  {
 
266
                    a=b;
 
267
                    break;
 
268
                  }
 
269
              }
 
270
          }
 
271
      }
 
272
    PolyhedralFan ret(0);
 
273
 
 
274
    return ret;
 
275
  }
 
276
  int main()
 
277
  {
 
278
    IntegerMatrix A=rowsToIntegerMatrix(FileParser(Stdin).parseIntegerVectorList()).transposed();
 
279
 
 
280
    int n=A.getWidth();
 
281
 
 
282
    SymmetryGroup s(n);
 
283
    if(symmetryOption.getValue())
 
284
      {
 
285
        IntegerVectorList generators=FileParser(Stdin).parseIntegerVectorList();
 
286
        for(IntegerVectorList::const_iterator i=generators.begin();i!=generators.end();i++)
 
287
          {
 
288
            assert(i->size()==n);
 
289
            FieldMatrix M1=integerMatrixToFieldMatrix(A,Q);
 
290
            FieldMatrix M2=integerMatrixToFieldMatrix(rowsToIntegerMatrix(SymmetryGroup::permuteIntegerVectorList(A.getRows(),*i)),Q);
 
291
            M1.reduce();
 
292
            M1.REformToRREform(true);
 
293
            M2.reduce();
 
294
            M2.REformToRREform(true);
 
295
 
 
296
            if(!(M1==M2))
 
297
              {
 
298
                AsciiPrinter(Stderr) << "Permutation "<< *i <<
 
299
                  " does not keep the configuration fixed.\n";
 
300
                assert(0);
 
301
              }
 
302
          }
 
303
        s.computeClosure(generators);
 
304
        s.createTrie();
 
305
      }
 
306
 
 
307
 
 
308
    if(scaleOption.getValue())
 
309
      {
 
310
        if(rank(A)!=A.getHeight())
 
311
          {
 
312
            cerr << "The vector configuration must have full rank in order to use the scale option.\n";
 
313
            assert(0);
 
314
          }
 
315
 
 
316
        int s=scaleOption.getValue();
 
317
 
 
318
        cout << "Input configuration:" << endl;
 
319
        AsciiPrinter(Stdout)<<A.transposed().getRows();
 
320
 
 
321
        IntegerVectorList empty;
 
322
        PolyhedralCone dual(A.transposed().getRows(),empty,n);
 
323
        dual.canonicalize();
 
324
        assert(dual.dimensionOfLinealitySpace()==0);
 
325
        IntegerVectorList inequalities=dual.extremeRays();
 
326
 
 
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];
 
331
 
 
332
        IntegerVectorList l=intsInPolytopeGivenIneqAndPt(M2,rightHandSide,v);
 
333
 
 
334
        IntegerVectorList lT=rowsToIntegerMatrix(l).transposed().getRows();
 
335
        lT.push_front(IntegerVector::allOnes(l.size()));
 
336
        l=rowsToIntegerMatrix(lT).transposed().getRows();
 
337
 
 
338
        cout << "New configuration:" << endl;
 
339
        AsciiPrinter(Stdout)<<l;
 
340
        A=rowsToIntegerMatrix(l).transposed();
 
341
      }
 
342
 
 
343
    /* If the vector configuration A does not have full rank then
 
344
       change coordinates. */
 
345
    if(rank(A)!=A.getHeight())
 
346
      {
 
347
        FieldMatrix M=integerMatrixToFieldMatrix(A,Q);
 
348
        M.reduce(false,true);//force integer operations - preserving volume
 
349
        M.removeZeroRows();
 
350
        A=fieldMatrixToIntegerMatrix(M);
 
351
      }
 
352
 
 
353
 
 
354
    Triangulation2 t(A);
 
355
 
 
356
    /* Convert a Triangulation to a Triangulation2 */
 
357
    {
 
358
      list<Triangulation::Cone> T=Triangulation::triangulate(A.transposed());
 
359
      for(list<Triangulation::Cone>::const_iterator i=T.begin();i!=T.end();i++)
 
360
        {
 
361
          IntegerVector v=i->size();
 
362
          int J=0;
 
363
          for(Triangulation::Cone::const_iterator j=i->begin();j!=i->end();j++,J++)
 
364
            v[J]=*j;
 
365
            t.bases.insert(v);
 
366
        }
 
367
    }
 
368
 
 
369
    if(searchOption.getValue())
 
370
      {
 
371
        PolyhedralFan f=automatic(t,t.totalVolume());
 
372
      }
 
373
    else if(hirschOption.getValue())
 
374
      {
 
375
        PolyhedralFan f=automaticHirsch(t);
 
376
      }
 
377
    else
 
378
{
 
379
                SymmetricTargetFanBuilder target(n,s);
 
380
 
 
381
                if(!optionRestrictingFan.getValue())
 
382
                {
 
383
                        SecondaryFanTraverser traverser(t);
 
384
                        symmetricTraverse(traverser,target,&s);
 
385
                }
 
386
                else
 
387
                {
 
388
                    PolyhedralFan f1=PolyhedralFan::readFan(optionRestrictingFan.getValue(),true,0,0,/*optionSymmetry.getValue()?&s:0*/0,false/*true*/);
 
389
 
 
390
                    for(PolyhedralFan::coneIterator i=f1.conesBegin();i!=f1.conesEnd();i++)
 
391
                        {
 
392
                        static int a;
 
393
                        log2 cerr<<"Processing Cone "<<a++<<" which has dimension "<<i->dimension()<<endl;
 
394
                        SecondaryFanTraverser traverser(triangulationWithFullDimensionalIntersection(t,*i),*i);
 
395
                                symmetricTraverse(traverser,target,&s);
 
396
                        }
 
397
                }
 
398
 
 
399
                target.getFanRef().printWithIndices(&pout,
 
400
                                            (symmetryOption.getValue()?FPF_group|FPF_conesCompressed:0)|
 
401
                                            (optionIgnoreCones.getValue()?0:FPF_conesExpanded)|
 
402
                                            FPF_maximalCones|FPF_cones,
 
403
                                            &s);
 
404
/*              target.getFanRef().printWithIndices(&p,
 
405
                                                                                        FPF_default|
 
406
                                                                                        (symmetryOption.getValue()?FPF_group|FPF_conesCompressed:0),
 
407
                                                                                        &s);
 
408
*/
 
409
/*      PolyhedralFan f=enumerate(t).negated();//Changing sign
 
410
 
 
411
        f.printWithIndices(&p,
 
412
                           FPF_default|
 
413
                           (symmetryOption.getValue()?FPF_group|FPF_conesCompressed:0),
 
414
                           &s);
 
415
  */
 
416
                }
 
417
    return 0;
 
418
  }
 
419
};
 
420
 
 
421
static SecondaryFanApplication theApplication;
 
422