1 /*
2 * gfanlib_symmetriccomplex.cpp
3 *
4 * Created on: Nov 16, 2010
5 * Author: anders
6 */
7
8 #include "gfanlib_symmetriccomplex.h"
9 #include "gfanlib_polymakefile.h"
10
11 #include <sstream>
12 #include <iostream>
13
14 namespace gfan{
15
Cone(std::set<int> const & indices_,int dimension_,Integer multiplicity_,bool sortWithSymmetry,SymmetricComplex const & complex)16 SymmetricComplex::Cone::Cone(std::set<int> const &indices_, int dimension_, Integer multiplicity_, bool sortWithSymmetry, SymmetricComplex const &complex):
17 isKnownToBeNonMaximalFlag(false),
18 dimension(dimension_),
19 multiplicity(multiplicity_),
20 sortKeyPermutation(complex.n)
21 {
22 indices=IntVector(indices_.size());
23 int j=0;
24 for(std::set<int>::const_iterator i=indices_.begin();i!=indices_.end();i++,j++)
25 indices[j]=*i;
26
27 ZMatrix const &vertices=complex.getVertices();
28 ZVector sum(vertices.getWidth());
29 for(unsigned i=0;i<indices.size();i++)
30 sum+=vertices[indices[i]];
31
32 if(sortWithSymmetry)
33 {
34 sortKey=complex.sym.orbitRepresentative(sum,&sortKeyPermutation);
35 }
36 else
37 {
38 sortKey=sum;
39 }
40 }
41
42
indexOfVertex(ZVector const & v) const43 int SymmetricComplex::indexOfVertex(ZVector const &v)const
44 {
45 // std::cerr<<v<<std::endl<<"In";
46 // for(std::map<ZVector,int>::const_iterator i =indexMap.begin();i!=indexMap.end();i++)std::cerr<<i->first;
47
48 std::map<ZVector,int>::const_iterator it=indexMap.find(v);
49 assert(it!=indexMap.end());
50 return it->second;
51 }
52
53
remap(SymmetricComplex & complex)54 void SymmetricComplex::Cone::remap(SymmetricComplex &complex)
55 {
56 ZMatrix const &vertices=complex.getVertices();
57 ZVector sum(vertices.getWidth());
58 for(unsigned i=0;i<indices.size();i++)
59 sum+=vertices[indices[i]];
60
61 unsigned n=sum.size();
62 Permutation const &bestPermutation=sortKeyPermutation;
63
64 assert(bestPermutation.size()==n);
65
66 IntVector indicesNew(indices.size());
67 int I=0;
68 for(unsigned i=0;i<indices.size();i++,I++)
69 {
70 ZVector ny=bestPermutation.apply(complex.vertices[indices[i]]);
71 std::map<ZVector,int>::const_iterator it=complex.indexMap.find(ny);
72 assert(it!=complex.indexMap.end());
73 indicesNew[I]=it->second;
74 }
75 indices=indicesNew;
76 }
77
78
indexSet() const79 std::set<int> SymmetricComplex::Cone::indexSet()const
80 {
81 std::set<int> ret;
82 for(unsigned i=0;i<indices.size();i++)
83 ret.insert(indices[i]);
84
85 return ret;
86 }
87
isSubsetOf(Cone const & c) const88 bool SymmetricComplex::Cone::isSubsetOf(Cone const &c)const
89 {
90 unsigned next=0;
91 for(unsigned i=0;i<indices.size();i++)
92 {
93 while(1)
94 {
95 if(next>=c.indices.size())return false;
96 if(indices[i]==c.indices[next])break;
97 next++;
98 }
99 }
100 return true;
101 }
102
103
permuted(Permutation const & permutation,SymmetricComplex const & complex,bool withSymmetry) const104 SymmetricComplex::Cone SymmetricComplex::Cone::permuted(Permutation const &permutation, SymmetricComplex const &complex, bool withSymmetry)const
105 {
106 std::set<int> r;
107 for(unsigned i=0;i<indices.size();i++)
108 {
109 ZVector ny=permutation.apply(complex.vertices[indices[i]]);
110 std::map<ZVector,int>::const_iterator it=complex.indexMap.find(ny);
111 if(it==complex.indexMap.end())
112 {
113 // AsciiPrinter(Stderr).printVector(complex.vertices[indices[i]]);
114 // AsciiPrinter(Stderr).printVector(ny);
115
116 assert(0);
117 }
118 r.insert(it->second);
119 }
120
121
122 return Cone(r,dimension,multiplicity,withSymmetry,complex);
123 }
124
125
operator <(Cone const & b) const126 bool SymmetricComplex::Cone::operator<(Cone const & b)const
127 {
128 return sortKey<b.sortKey;
129 }
130
131
isSimplicial(int linealityDim) const132 bool SymmetricComplex::Cone::isSimplicial(int linealityDim)const
133 {
134 return (indices.size()+linealityDim)==dimension;
135 }
136
137
orthogonalComplement(SymmetricComplex & complex) const138 ZMatrix SymmetricComplex::Cone::orthogonalComplement(SymmetricComplex &complex)const
139 {
140 ZMatrix l;
141 for(unsigned i=0;i<indices.size();i++)
142 l.appendRow(complex.vertices[indices[i]]);
143
144 return l.reduceAndComputeKernel();
145 // FieldMatrix m=integerMatrixToFieldMatrix(rowsToIntegerMatrix(l,complex.n),Q);
146 // return fieldMatrixToIntegerMatrixPrimitive(m.reduceAndComputeKernel()).getRows();
147 }
148
149
SymmetricComplex(ZMatrix const & rays,ZMatrix const & linealitySpace_,SymmetryGroup const & sym_)150 SymmetricComplex::SymmetricComplex(ZMatrix const &rays, ZMatrix const &linealitySpace_, SymmetryGroup const &sym_):
151 n(rays.getWidth()),
152 linealitySpace(canonicalizeSubspace(linealitySpace_)),
153 sym(sym_),
154 dimension(-1)
155 {
156 assert(rays.getWidth()==linealitySpace.getWidth());
157 // vertices=rowsToIntegerMatrix(v,n);
158 vertices=rays;
159
160 for(int i=0;i<vertices.getHeight();i++)indexMap[vertices[i]]=i;
161 }
162
163
contains(Cone const & c) const164 bool SymmetricComplex::contains(Cone const &c)const
165 {
166 Cone temp=c;
167 return cones.find(temp)!=cones.end();///////////////////!!!!!!!!!!!!!!!!!!!!!!!
168 }
169
170
insert(Cone const & c)171 void SymmetricComplex::insert(Cone const &c)
172 {
173 if(c.dimension>dimension)dimension=c.dimension;
174 if(!contains(c))//#2
175 {
176 cones.insert(c);
177 }
178 else
179 {
180 if(c.isKnownToBeNonMaximal()){cones.erase(c);cones.insert(c);}// mark as non-maximal
181 }
182 }
183
184
getLinDim() const185 int SymmetricComplex::getLinDim()const
186 {
187 return linealitySpace.getHeight();
188 }
189
getMaxDim() const190 int SymmetricComplex::getMaxDim()const
191 {
192 return dimension;
193 }
194
195
getMinDim() const196 int SymmetricComplex::getMinDim()const
197 {
198 int ret=100000;
199 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
200 {
201 if(i->dimension<ret)ret=i->dimension;
202 }
203 return ret;
204 }
205
206
isMaximal(Cone const & c) const207 bool SymmetricComplex::isMaximal(Cone const &c)const
208 {
209 if(c.isKnownToBeNonMaximal())return false;
210 if(c.dimension==dimension)return true;
211 for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
212 {
213 Cone c2=c.permuted(*k,*this,false);
214 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
215 {
216 if(i->dimension>c.dimension)
217 if(c2.isSubsetOf(*i) && !i->isSubsetOf(c2))return false;
218 }
219 }
220 return true;
221 }
222
223 #if 0
224 IntVector SymmetricComplex::dimensionsAtInfinity()const
225 {
226 /* Using a double description like method this routine computes the
227 dimension of the intersection of each cone in the complex with
228 the plane x_0=0 */
229 IntVector ret(cones.size());
230
231 int I=0;
232 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++)
233 {
234 ZMatrix raysAtInfinity;
235 for(int j=0;j<i->indices.size();j++)
236 {
237 if(vertices[i->indices[j]][0]==0)raysAtInfinity.push_back(vertices[i->indices[j]]);
238 for(vector<int>::const_iterator k=j;k!=i->indices.end();k++)
239 if(vertices[*j][0]*vertices[*k][0]<0)
240 raysAtInfinity.push_back(((vertices[*j][0]>0)?1:-1)*(vertices[*j][0])*vertices[*k]+
241 ((vertices[*k][0]>0)?1:-1)*(vertices[*k][0])*vertices[*j]);
242 }
243 ret[I]=rankOfMatrix(raysAtInfinity);
244 }
245 return ret;
246 }
247 #endif
248
buildConeLists(bool onlyMaximal,bool compressed,std::vector<std::vector<IntVector>> * conelist,std::vector<std::vector<Integer>> * multiplicities) const249 void SymmetricComplex::buildConeLists(bool onlyMaximal, bool compressed, std::vector<std::vector<IntVector > >*conelist, std::vector<std::vector<Integer > > *multiplicities)const
250 {
251 int dimLow=this->linealitySpace.getHeight();
252 int dimHigh=this->getMaxDim();
253 if(dimHigh<dimLow)dimHigh=dimLow-1;
254 if(conelist)*conelist=std::vector<std::vector<IntVector> >(dimHigh-dimLow+1);
255 if(multiplicities)*multiplicities=std::vector<std::vector<Integer> >(dimHigh-dimLow+1);
256 for(int d=dimLow;d<=dimHigh;d++)
257 {
258 int numberOfOrbitsOutput=0;
259 int numberOfOrbitsOfThisDimension=0;
260 // bool newDimension=true;
261 {
262 int I=0;
263 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++)
264 if(i->dimension==d)
265 {
266 numberOfOrbitsOfThisDimension++;
267 if(!onlyMaximal || isMaximal(*i))
268 {
269 numberOfOrbitsOutput++;
270 // bool isMax=isMaximal(*i);
271 // bool newOrbit=true;
272 std::set<std::pair<std::set<int>,Integer> > temp;
273 for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
274 {
275 Cone temp1=i->permuted(*k,*this,false);
276 temp.insert(std::pair<std::set<int>,Integer>(temp1.indexSet(),temp1.multiplicity));
277 if(compressed)break;
278 }
279 for(std::set<std::pair<std::set<int>,Integer> >::const_iterator j=temp.begin();j!=temp.end();j++)
280 {
281 IntVector temp;
282 for(std::set<int>::const_iterator k=j->first.begin();k!=j->first.end();k++)temp.push_back(*k);
283 if(conelist)(*conelist)[d-dimLow].push_back(temp);
284 if(multiplicities)(*multiplicities)[d-dimLow].push_back(j->second);
285 /* if(isMax)if(multiplicities)
286 {
287
288 *multiplicities << i->multiplicity;
289 if(group)if(newOrbit)*multiplicities << "\t# New orbit";
290 if(newDimension)*multiplicities << "\t# Dimension "<<d;
291 *multiplicities << std::endl;
292 }*/
293 // newOrbit=false;
294 // newDimension=false;
295 }
296 }
297 }
298 }
299 }
300
301 }
302
toStringJustCones(int dimLow,int dimHigh,bool onlyMaximal,bool group,std::ostream * multiplicities,bool compressed,bool tPlaneSort) const303 std::string SymmetricComplex::toStringJustCones(int dimLow, int dimHigh, bool onlyMaximal, bool group, std::ostream *multiplicities, bool compressed, bool tPlaneSort)const
304 {
305 std::stringstream ret;
306
307 ZVector additionalSortKeys(cones.size());
308 // if(tPlaneSort)additionalSortKeys=dimensionsAtInfinity();
309 // Integer lowKey=additionalSortKeys.min();
310 // Integer highKey=additionalSortKeys.max();
311
312 for(int d=dimLow;d<=dimHigh;d++)
313 {
314 int numberOfOrbitsOutput=0;
315 int numberOfOrbitsOfThisDimension=0;
316 bool newDimension=true;
317 // for(int key=lowKey;key<=highKey;key++)
318 {
319 int I=0;
320 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++)
321 // if(additionalSortKeys[I]==key)
322 if(i->dimension==d)
323 {
324 numberOfOrbitsOfThisDimension++;
325 if(!onlyMaximal || isMaximal(*i))
326 {
327 numberOfOrbitsOutput++;
328 bool isMax=isMaximal(*i);
329 bool newOrbit=true;
330 std::set<std::set<int> > temp;
331 for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
332 {
333 Cone temp1=i->permuted(*k,*this,false);
334 temp.insert(temp1.indexSet());
335 if(compressed)break;
336 }
337 for(std::set<std::set<int> >::const_iterator j=temp.begin();j!=temp.end();j++)
338 {
339 ret << "{";
340 for(std::set<int>::const_iterator a=j->begin();a!=j->end();a++)
341 {
342 if(a!=j->begin())ret<<" ";
343 ret << *a;
344 }
345 ret << "}";
346 if(group)if(newOrbit)ret << "\t# New orbit";
347 if(newDimension)ret << "\t# Dimension "<<d;
348 ret <<std::endl;
349 if(isMax)if(multiplicities)
350 {
351 *multiplicities << i->multiplicity;
352 if(group)if(newOrbit)*multiplicities << "\t# New orbit";
353 if(newDimension)*multiplicities << "\t# Dimension "<<d;
354 *multiplicities << std::endl;
355 }
356 newOrbit=false;
357 newDimension=false;
358 }
359 }
360 }
361 }
362 }
363
364 return ret.str();
365 }
366
367
fvector(bool boundedPart) const368 ZVector SymmetricComplex::fvector(bool boundedPart)const
369 {
370 int min=getMinDim();
371 int dimHigh=getMaxDim();
372 if(dimHigh<min)dimHigh=min-1;
373 ZVector ret(dimHigh-min+1);
374
375 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
376 {
377 bool doAdd=!boundedPart;
378 if(boundedPart)
379 {
380 bool isBounded=true;
381 for(unsigned j=0;j<i->indices.size();j++)
382 if(vertices[i->indices[j]][0].sign()==0)isBounded=false;
383 doAdd=isBounded;
384 }
385 if(doAdd)
386 ret[i->dimension-min]+=Integer(sym.orbitSize(i->sortKey));
387 }
388 return ret;
389 }
390
391
isPure() const392 bool SymmetricComplex::isPure()const
393 {
394 int dim=-1;
395 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
396 {
397 if(isMaximal(*i))
398 {
399 int dim2=i->dimension;
400 if(dim==-1)dim=dim2;
401 if(dim!=dim2)return false;
402 }
403 }
404 return true;
405 }
406
407
isSimplicial() const408 bool SymmetricComplex::isSimplicial()const
409 {
410 int linealityDim=getMinDim();
411 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
412 if(!i->isSimplicial(linealityDim))
413 return false;
414 return true;
415 }
416
417
remap()418 void SymmetricComplex::remap()
419 {
420 for(ConeContainer::iterator i=cones.begin();i!=cones.end();i++)
421 {
422 Cone const&j=*i;
423 Cone &j2=const_cast<Cone&>(j);//DANGER: cast away const. This does not change the sort key in the container, so should be OK.
424 j2.remap(*this);
425 }
426 }
427
428
numberOfConesOfDimension(int d) const429 int SymmetricComplex::numberOfConesOfDimension(int d)const
430 {
431 assert(sym.isTrivial());
432
433 int ret=0;
434 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
435 if(d==i->dimension)
436 {
437 ret++;
438 }
439 return ret;
440 }
441
442
dimensionIndex(Cone const & c)443 int SymmetricComplex::dimensionIndex(Cone const &c)
444 {
445 assert(sym.isTrivial());
446
447 int ret=0;
448 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
449 if(c.dimension==i->dimension)
450 {
451 if(!(c<*i)&&!(*i<c))
452 return ret;
453 else
454 ret++;
455 }
456 return ret;
457 }
458
459 #if 0
460 void SymmetricComplex::boundary(Cone const &c, vector<int> &indices_, vector<int> &signs)
461 {
462 indices_=vector<int>();
463 signs=vector<int>();
464 int d=c.dimension;
465
466
467 IntegerVectorList l;
468 for(int i=0;i<c.indices.size();i++)
469 l.push_back(vertices[c.indices[i]]);
470 IntegerVectorList facetNormals=PolyhedralCone(l,IntegerVectorList(),n).extremeRays();
471 IntegerVectorList complementBasis=c.orthogonalComplement(*this);
472 for(IntegerVectorList::const_iterator i=facetNormals.begin();i!=facetNormals.end();i++)
473 {
474 IntegerVectorList complementBasis1=complementBasis;
475 complementBasis1.push_back(*i);
476 FieldMatrix m=integerMatrixToFieldMatrix(rowsToIntegerMatrix(complementBasis1,n),Q);
477 IntegerVectorList completion=fieldMatrixToIntegerMatrixPrimitive(m.reduceAndComputeKernel()).getRows();
478 for(IntegerVectorList::const_iterator j=completion.begin();j!=completion.end();j++)complementBasis1.push_back(*j);
479 int sign=determinantSign(complementBasis1);
480
481 set<int> indices;
482 for(vector<int>::const_iterator j=c.indices.begin();j!=c.indices.end();j++)if(dotLong(vertices[*j],*i)==0)indices.insert(*j);
483 Cone facet(indices,d-1,1,true,*this);
484 IntegerVectorList complementBasis2=facet.orthogonalComplement(*this);
485 for(IntegerVectorList::const_iterator j=completion.begin();j!=completion.end();j++)complementBasis2.push_back(*j);
486 indices_.push_back(dimensionIndex(facet));
487 signs.push_back(sign*determinantSign(complementBasis2));
488 }
489 }
490
491
492 IntegerMatrix SymmetricComplex::boundaryMap(int d)
493 {
494 assert(sym.isTrivial());
495
496 IntegerMatrix ret(numberOfConesOfDimension(d-1),numberOfConesOfDimension(d));
497
498 for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
499 if(d==i->dimension)
500 {
501 int I=dimensionIndex(*i);
502 vector<int> indices;
503 vector<int> signs;
504 boundary(*i,indices,signs);
505 for(int j=0;j<indices.size();j++)
506 {
507 ret[indices[j]][I]+=signs[j];
508 }
509 }
510 return ret;
511 }
512 #endif
513
514
toString(int flags) const515 std::string SymmetricComplex::toString(int flags)const
516 {
517 PolymakeFile polymakeFile;
518 polymakeFile.create("NONAME","PolyhedralFan","PolyhedralFan",flags&FPF_xml);
519
520
521
522
523
524 polymakeFile.writeCardinalProperty("AMBIENT_DIM",n);
525 polymakeFile.writeCardinalProperty("DIM",getMaxDim());
526 polymakeFile.writeCardinalProperty("LINEALITY_DIM",linealitySpace.getHeight());
527 // polymakeFile.writeMatrixProperty("RAYS",rays,true,comments);
528 polymakeFile.writeMatrixProperty("RAYS",vertices,true);
529 polymakeFile.writeCardinalProperty("N_RAYS",vertices.getHeight());
530
531
532 polymakeFile.writeMatrixProperty("LINEALITY_SPACE",linealitySpace,n);
533 polymakeFile.writeMatrixProperty("ORTH_LINEALITY_SPACE",kernel(linealitySpace),n);
534
535 /*
536 if(flags & FPF_primitiveRays)
537 {
538 ZMatrix primitiveRays;
539 for(int i=0;i<rays.getHeight();i++)
540 for(PolyhedralConeList::const_iterator j=cones.begin();j!=cones.end();j++)
541 if(j->contains(*i)&&(j->dimensionOfLinealitySpace()+1==j->dimension()))
542 primitiveRays.push_back(j->semiGroupGeneratorOfRay());
543
544 polymakeFile.writeMatrixProperty("PRIMITIVE_RAYS",rowsToIntegerMatrix(primitiveRays,n));
545 }
546 */
547 #if 0
548 ZMatrix generatorsOfLinealitySpace=cones.begin()->generatorsOfLinealitySpace();
549
550 log1 fprintf(Stderr,"Building symmetric complex.\n");
551 for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
552 {
553 {
554 static int t;
555 // log1 fprintf(Stderr,"Adding faces of cone %i\n",t++);
556 }
557 // gfan_log2 fprintf(Stderr,"Dim: %i\n",i->dimension());
558
559 addFacesToSymmetricComplex(symCom,*i,i->getHalfSpaces(),generatorsOfLinealitySpace);
560 }
561
562 // log1 cerr<<"Remapping";
563 symCom.remap();
564 // log1 cerr<<"Done remapping";
565
566
567 PolyhedralFan f=*this;
568 #endif
569
570 // log1 fprintf(Stderr,"Computing f-vector.\n");
571 ZVector fvector=this->fvector();
572 polymakeFile.writeCardinalVectorProperty("F_VECTOR",fvector);
573 // log1 fprintf(Stderr,"Done computing f-vector.\n");
574
575 if(flags&FPF_boundedInfo)
576 {
577 // log1 fprintf(Stderr,"Computing bounded f-vector.\n");
578 ZVector fvectorBounded=this->fvector(true);
579 polymakeFile.writeCardinalVectorProperty("F_VECTOR_BOUNDED",fvectorBounded);
580 // log1 fprintf(Stderr,"Done computing bounded f-vector.\n");
581 }
582 #if 0
583 {
584 Integer euler;
585 int mul=-1;
586 for(int i=0;i<fvector.size();i++,mul*=-1)euler+=Integer(mul)*fvector[i];
587 polymakeFile.writeCardinalProperty("MY_EULER",euler);
588 }
589 #endif
590 // log1 fprintf(Stderr,"Checking if complex is simplicial and pure.\n");
591 polymakeFile.writeCardinalProperty("SIMPLICIAL",isSimplicial());
592 polymakeFile.writeCardinalProperty("PURE",isPure());
593 // log1 fprintf(Stderr,"Done checking.\n");
594
595
596 if(flags&FPF_cones)polymakeFile.writeStringProperty("CONES",toStringJustCones(getMinDim(),getMaxDim(),false,flags&FPF_group, 0,false,flags&FPF_tPlaneSort));
597 if(flags&FPF_maximalCones)polymakeFile.writeStringProperty("MAXIMAL_CONES",toStringJustCones(getMinDim(),getMaxDim(),true,flags&FPF_group, 0,false,flags&FPF_tPlaneSort));
598 if(flags&FPF_conesCompressed)polymakeFile.writeStringProperty("CONES_ORBITS",toStringJustCones(getMinDim(),getMaxDim(),false,flags&FPF_group, 0,true,flags&FPF_tPlaneSort));
599 if((flags&FPF_conesCompressed) && (flags&FPF_maximalCones))polymakeFile.writeStringProperty("MAXIMAL_CONES_ORBITS",toStringJustCones(getMinDim(),getMaxDim(),true,flags&FPF_group, 0,true,flags&FPF_tPlaneSort));
600
601 if(!sym.isTrivial())
602 {
603 polymakeFile.writeMatrixProperty("SYMMETRY_GENERATORS",IntToZMatrix(sym.getGenerators()));
604 }
605
606 std::stringstream s;
607 polymakeFile.writeStream(s);
608 return s.str();
609
610 #if 0
611
612 if(flags&FPF_conesCompressed)
613 {
614 // log1 fprintf(Stderr,"Producing list of cones up to symmetry.\n");
615 polymakeFile.writeStringProperty("CONES_ORBITS",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),false,flags&FPF_group,0,true,flags&FPF_tPlaneSort));
616 // log1 fprintf(Stderr,"Done producing list of cones up to symmetry.\n");
617 // log1 fprintf(Stderr,"Producing list of maximal cones up to symmetry.\n");
618 stringstream multiplicities;
619 polymakeFile.writeStringProperty("MAXIMAL_CONES_ORBITS",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),true,flags&FPF_group, &multiplicities,true,flags&FPF_tPlaneSort));
620 if(flags&FPF_multiplicities)polymakeFile.writeStringProperty("MULTIPLICITIES_ORBITS",multiplicities.str());
621 // log1 fprintf(Stderr,"Done producing list of maximal cones up to symmetry.\n");
622 }
623
624 if(flags&FPF_conesExpanded)
625 {
626 if(flags&FPF_cones)
627 {
628 // log1 fprintf(Stderr,"Producing list of cones.\n");
629 polymakeFile.writeStringProperty("CONES",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),false,flags&FPF_group,0,false,flags&FPF_tPlaneSort));
630 // log1 fprintf(Stderr,"Done producing list of cones.\n");
631 }
632 if(flags&FPF_maximalCones)
633 {
634 // log1 fprintf(Stderr,"Producing list of maximal cones.\n");
635 stringstream multiplicities;
636 polymakeFile.writeStringProperty("MAXIMAL_CONES",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),true,flags&FPF_group, &multiplicities,false,flags&FPF_tPlaneSort));
637 if(flags&FPF_multiplicities)polymakeFile.writeStringProperty("MULTIPLICITIES",multiplicities.str());
638 // log1 fprintf(Stderr,"Done producing list of maximal cones.\n");
639 }
640 }
641 #endif
642 #if 0
643 if(flags&FPF_values)
644 {
645 {
646 ZMatrix values;
647 for(int i=0;i<linealitySpaceGenerators.getHeight();i++)
648 {
649 ZVector v(1);
650 v[0]=evaluatePiecewiseLinearFunction(linealitySpaceGenerators[i]);
651 values.appendRow(v);
652 }
653 polymakeFile.writeMatrixProperty("LINEALITY_VALUES",rowsToIntegerMatrix(values,1));
654 }
655 {
656 ZMatrix values;
657 for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++)
658 {
659 ZVector v(1);
660 v[0]=evaluatePiecewiseLinearFunction(*i);
661 values.push_back(v);
662 }
663 polymakeFile.writeMatrixProperty("RAY_VALUES",rowsToIntegerMatrix(values,1));
664 }
665 }
666 #endif
667
668
669 // log1 fprintf(Stderr,"Producing final string for output.\n");
670 /* stringstream s;
671 polymakeFile.writeStream(s);
672 string S=s.str();
673 // log1 fprintf(Stderr,"Printing string.\n");
674 p->printString(S.c_str());
675 */// log1 fprintf(Stderr,"Done printing string.\n");
676 }
677
makeZCone(IntVector const & indices) const678 ZCone SymmetricComplex::makeZCone(IntVector const &indices)const
679 {
680 ZMatrix generators(indices.size(),getAmbientDimension());
681 for(unsigned i=0;i<indices.size();i++)
682 generators[i]=vertices[indices[i]];
683 return ZCone::givenByRays(generators,linealitySpace);
684 }
685 }
686