source:git/gfanlib/gfanlib_symmetriccomplex.cpp@74a91c9

jengelh-datetimespielwiese
Last change on this file since 74a91c9 was 74a91c9, checked in by Frank Seelisch <seelisch@…>, 13 years ago
new gfan lib version by Anders Jensen git-svn-id: file:///usr/local/Singular/svn/trunk@13668 2c84dea3-7e68-4137-9b89-c4e89433aadc
• Property mode set to `100644`
File size: 20.5 KB
Line
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
14namespace gfan{
15
16SymmetricComplex::Cone::Cone(std::set<int> const &indices_, int dimension_, Integer multiplicity_, bool sortWithSymmetry, SymmetricComplex const &complex):
17  dimension(dimension_),
18  multiplicity(multiplicity_),
19  isKnownToBeNonMaximalFlag(false),
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(int 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
43int 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
54void SymmetricComplex::Cone::remap(SymmetricComplex &complex)
55{
56  ZMatrix const &vertices=complex.getVertices();
57  ZVector sum(vertices.getWidth());
58  for(int i=0;i<indices.size();i++)
59    sum+=vertices[indices[i]];
60
61  int 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(int 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
79std::set<int> SymmetricComplex::Cone::indexSet()const
80{
81  std::set<int> ret;
82  for(int i=0;i<indices.size();i++)
83    ret.insert(indices[i]);
84
85  return ret;
86}
87
88bool SymmetricComplex::Cone::isSubsetOf(Cone const &c)const
89{
90  int next=0;
91  for(int 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
104SymmetricComplex::Cone SymmetricComplex::Cone::permuted(Permutation const &permutation, SymmetricComplex const &complex, bool withSymmetry)const
105{
106  std::set<int> r;
107  for(int 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
126bool SymmetricComplex::Cone::operator<(Cone const & b)const
127{
128  return sortKey<b.sortKey;
129}
130
131
132bool SymmetricComplex::Cone::isSimplicial(int linealityDim)const
133{
134  return (indices.size()+linealityDim)==dimension;
135}
136
137
138ZMatrix SymmetricComplex::Cone::orthogonalComplement(SymmetricComplex &complex)const
139{
140  ZMatrix l;
141  for(int 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
150SymmetricComplex::SymmetricComplex(ZMatrix const &rays, ZMatrix const &linealitySpace_, SymmetryGroup const &sym_):
151  n(rays.getWidth()),
152  sym(sym_),
153  dimension(-1),
154  linealitySpace(canonicalizeSubspace(linealitySpace_))
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
164bool SymmetricComplex::contains(Cone const &c)const
165{
166  Cone temp=c;
167  return cones.find(temp)!=cones.end();///////////////////!!!!!!!!!!!!!!!!!!!!!!!
168}
169
170
171void 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
185int SymmetricComplex::getMaxDim()const
186{
187  return dimension;
188}
189
190
191int SymmetricComplex::getMinDim()const
192{
193  int ret=100000;
194  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
195    {
196      if(i->dimension<ret)ret=i->dimension;
197    }
198  return ret;
199}
200
201
202bool SymmetricComplex::isMaximal(Cone const &c)const
203{
204  if(c.isKnownToBeNonMaximal())return false;
205  if(c.dimension==dimension)return true;
206  for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
207    {
208      Cone c2=c.permuted(*k,*this,false);
209      for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
210        {
211          if(i->dimension>c.dimension)
212            if(c2.isSubsetOf(*i) && !i->isSubsetOf(c2))return false;
213        }
214    }
215  return true;
216}
217
218/*
219IntVector SymmetricComplex::dimensionsAtInfinity()const
220{
221  /* Using a double description like method this routine computes the
222     dimension of the intersection of each cone in the complex with
223     the plane x_0=0 */
224/*
225  IntVector ret(cones.size());
226
227  int I=0;
228  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++)
229    {
230      ZMatrix raysAtInfinity;
231      for(int j=0;j<i->indices.size();j++)
232        {
233          if(vertices[i->indices[j]][0]==0)raysAtInfinity.push_back(vertices[i->indices[j]]);
234          for(vector<int>::const_iterator k=j;k!=i->indices.end();k++)
235            if(vertices[*j][0]*vertices[*k][0]<0)
236              raysAtInfinity.push_back(((vertices[*j][0]>0)?1:-1)*(vertices[*j][0])*vertices[*k]+
237                                       ((vertices[*k][0]>0)?1:-1)*(vertices[*k][0])*vertices[*j]);
238        }
239      ret[I]=rankOfMatrix(raysAtInfinity);
240    }
241  return ret;
242}
243*/
244
245void SymmetricComplex::buildConeLists(bool onlyMaximal, bool compressed, std::vector<std::vector<IntVector > >*conelist/*, ZMatrix *multiplicities*/)const
246{
247  int dimLow=this->linealitySpace.getHeight();
248  int dimHigh=this->getMaxDim();
249  if(conelist)*conelist=std::vector<std::vector<IntVector> >(dimHigh-dimLow+1);
250
251  for(int d=dimLow;d<=dimHigh;d++)
252    {
253      int numberOfOrbitsOutput=0;
254      int numberOfOrbitsOfThisDimension=0;
255      bool newDimension=true;
256        {
257          int I=0;
258          for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++)
259                  if(i->dimension==d)
260                    {
261                      numberOfOrbitsOfThisDimension++;
262              if(!onlyMaximal || isMaximal(*i))
263                {
264                  numberOfOrbitsOutput++;
265                  bool isMax=isMaximal(*i);
266                  bool newOrbit=true;
267                  std::set<std::set<int> > temp;
268                    for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
269                      {
270                        Cone temp1=i->permuted(*k,*this,false);
271                        temp.insert(temp1.indexSet());
272                        if(compressed)break;
273                    }
274                  for(std::set<std::set<int> >::const_iterator j=temp.begin();j!=temp.end();j++)
275                    {
276                      IntVector temp;
277                      for(std::set<int>::const_iterator k=j->begin();k!=j->end();k++)temp.push_back(*k);
278                      if(conelist)(*conelist)[d-dimLow].push_back(temp);
279 /*                     if(isMax)if(multiplicities)
280                        {
281
282                          *multiplicities << i->multiplicity;
283                          if(group)if(newOrbit)*multiplicities << "\t# New orbit";
284                          if(newDimension)*multiplicities << "\t# Dimension "<<d;
285                          *multiplicities << std::endl;
286                        }*/
287                      newOrbit=false;
288                      newDimension=false;
289                    }
290              }
291                    }
292        }
293    }
294
295
296}
297
298std::string SymmetricComplex::toStringJustCones(int dimLow, int dimHigh, bool onlyMaximal, bool group, std::ostream *multiplicities, bool compressed, bool tPlaneSort)const
299{
300  std::stringstream ret;
301
306
307  for(int d=dimLow;d<=dimHigh;d++)
308    {
309      int numberOfOrbitsOutput=0;
310      int numberOfOrbitsOfThisDimension=0;
311      bool newDimension=true;
312 //     for(int key=lowKey;key<=highKey;key++)
313        {
314          int I=0;
315          for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++)
317                  if(i->dimension==d)
318                    {
319                      numberOfOrbitsOfThisDimension++;
320              if(!onlyMaximal || isMaximal(*i))
321                {
322                  numberOfOrbitsOutput++;
323                  bool isMax=isMaximal(*i);
324                  bool newOrbit=true;
325                  std::set<std::set<int> > temp;
326                    for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
327                      {
328                        Cone temp1=i->permuted(*k,*this,false);
329                        temp.insert(temp1.indexSet());
330                        if(compressed)break;
331                    }
332                  for(std::set<std::set<int> >::const_iterator j=temp.begin();j!=temp.end();j++)
333                    {
334                      ret << "{";
335                      for(std::set<int>::const_iterator a=j->begin();a!=j->end();a++)
336                        {
337                          if(a!=j->begin())ret<<" ";
338                          ret << *a;
339                        }
340                      ret << "}";
341                      if(group)if(newOrbit)ret << "\t# New orbit";
342                      if(newDimension)ret << "\t# Dimension "<<d;
343                      ret <<std::endl;
344                      if(isMax)if(multiplicities)
345                        {
346                          *multiplicities << i->multiplicity;
347                          if(group)if(newOrbit)*multiplicities << "\t# New orbit";
348                          if(newDimension)*multiplicities << "\t# Dimension "<<d;
349                          *multiplicities << std::endl;
350                        }
351                      newOrbit=false;
352                      newDimension=false;
353                    }
354              }
355                    }
356        }
357    }
358
359  return ret.str();
360}
361
362
363ZVector SymmetricComplex::fvector(bool boundedPart)const
364{
365  int min=getMinDim();
366  ZVector ret(getMaxDim()-min+1);
367
368  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
369    {
371      if(boundedPart)
372        {
373          bool isBounded=true;
374          for(int j=0;j<i->indices.size();j++)
375            if(vertices[i->indices[j]][0].sign()==0)isBounded=false;
377        }
379        ret[i->dimension-min]+=Integer(sym.orbitSize(i->sortKey));
380    }
381  return ret;
382}
383
384
385bool SymmetricComplex::isPure()const
386{
387  int dim=-1;
388  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
389    {
390      if(isMaximal(*i))
391        {
392          int dim2=i->dimension;
393          if(dim==-1)dim=dim2;
394          if(dim!=dim2)return false;
395        }
396    }
397  return true;
398}
399
400
401bool SymmetricComplex::isSimplicial()const
402{
403  int linealityDim=getMinDim();
404  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
405    if(!i->isSimplicial(linealityDim))
406      return false;
407  return true;
408}
409
410
411void SymmetricComplex::remap()
412{
413  for(ConeContainer::iterator i=cones.begin();i!=cones.end();i++)
414    {
415      Cone const&j=*i;
416      Cone &j2=const_cast<Cone&>(j);//DANGER: cast away const. This does not change the sort key in the container, so should be OK.
417      j2.remap(*this);
418    }
419}
420
421
422int SymmetricComplex::numberOfConesOfDimension(int d)const
423{
424  assert(sym.isTrivial());
425
426  int ret=0;
427  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
428    if(d==i->dimension)
429      {
430        ret++;
431      }
432  return ret;
433}
434
435
436int SymmetricComplex::dimensionIndex(Cone const &c)
437{
438  assert(sym.isTrivial());
439
440  int ret=0;
441  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
442    if(c.dimension==i->dimension)
443      {
444        if(!(c<*i)&&!(*i<c))
445          return ret;
446        else
447          ret++;
448      }
449  return ret;
450}
451
452#if 0
453void SymmetricComplex::boundary(Cone const &c, vector<int> &indices_, vector<int> &signs)
454{
455  indices_=vector<int>();
456  signs=vector<int>();
457  int d=c.dimension;
458
459
460  IntegerVectorList l;
461  for(int i=0;i<c.indices.size();i++)
462    l.push_back(vertices[c.indices[i]]);
463  IntegerVectorList facetNormals=PolyhedralCone(l,IntegerVectorList(),n).extremeRays();
464  IntegerVectorList complementBasis=c.orthogonalComplement(*this);
465  for(IntegerVectorList::const_iterator i=facetNormals.begin();i!=facetNormals.end();i++)
466    {
467      IntegerVectorList complementBasis1=complementBasis;
468      complementBasis1.push_back(*i);
469      FieldMatrix m=integerMatrixToFieldMatrix(rowsToIntegerMatrix(complementBasis1,n),Q);
470      IntegerVectorList completion=fieldMatrixToIntegerMatrixPrimitive(m.reduceAndComputeKernel()).getRows();
471      for(IntegerVectorList::const_iterator j=completion.begin();j!=completion.end();j++)complementBasis1.push_back(*j);
472      int sign=determinantSign(complementBasis1);
473
474      set<int> indices;
475      for(vector<int>::const_iterator j=c.indices.begin();j!=c.indices.end();j++)if(dotLong(vertices[*j],*i)==0)indices.insert(*j);
476      Cone facet(indices,d-1,1,true,*this);
477      IntegerVectorList complementBasis2=facet.orthogonalComplement(*this);
478      for(IntegerVectorList::const_iterator j=completion.begin();j!=completion.end();j++)complementBasis2.push_back(*j);
479      indices_.push_back(dimensionIndex(facet));
480      signs.push_back(sign*determinantSign(complementBasis2));
481    }
482}
483
484
485IntegerMatrix SymmetricComplex::boundaryMap(int d)
486{
487  assert(sym.isTrivial());
488
489  IntegerMatrix ret(numberOfConesOfDimension(d-1),numberOfConesOfDimension(d));
490
491  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
492    if(d==i->dimension)
493      {
494        int I=dimensionIndex(*i);
495        vector<int> indices;
496        vector<int> signs;
497        boundary(*i,indices,signs);
498        for(int j=0;j<indices.size();j++)
499          {
500              ret[indices[j]][I]+=signs[j];
501          }
502      }
503  return ret;
504}
505#endif
506
507
508  std::string SymmetricComplex::toString(int flags)const
509  {
510    PolymakeFile polymakeFile;
511    polymakeFile.create("NONAME","PolyhedralFan","PolyhedralFan",flags&FPF_xml);
512
513
514
515
516
517    polymakeFile.writeCardinalProperty("AMBIENT_DIM",n);
518    polymakeFile.writeCardinalProperty("DIM",getMaxDim());
519    polymakeFile.writeCardinalProperty("LINEALITY_DIM",linealitySpace.getHeight());
521        polymakeFile.writeMatrixProperty("RAYS",vertices,true);
522    polymakeFile.writeCardinalProperty("N_RAYS",vertices.getHeight());
523
524
525    polymakeFile.writeMatrixProperty("LINEALITY_SPACE",kernel(linealitySpace),n);
526    polymakeFile.writeMatrixProperty("ORTH_LINEALITY_SPACE",linealitySpace,n);
527
528/*
529    if(flags & FPF_primitiveRays)
530    {
531      ZMatrix primitiveRays;
532      for(int i=0;i<rays.getHeight();i++)
533        for(PolyhedralConeList::const_iterator j=cones.begin();j!=cones.end();j++)
534          if(j->contains(*i)&&(j->dimensionOfLinealitySpace()+1==j->dimension()))
535            primitiveRays.push_back(j->semiGroupGeneratorOfRay());
536
537      polymakeFile.writeMatrixProperty("PRIMITIVE_RAYS",rowsToIntegerMatrix(primitiveRays,n));
538    }
539*/
540#if 0
541    ZMatrix generatorsOfLinealitySpace=cones.begin()->generatorsOfLinealitySpace();
542
543    log1 fprintf(Stderr,"Building symmetric complex.\n");
544    for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
545      {
546        {
547          static int t;
548  //        log1 fprintf(Stderr,"Adding faces of cone %i\n",t++);
549        }
550  //      log2 fprintf(Stderr,"Dim: %i\n",i->dimension());
551
553      }
554
555  //  log1 cerr<<"Remapping";
556    symCom.remap();
557  //  log1 cerr<<"Done remapping";
558
559
560    PolyhedralFan f=*this;
561#endif
562
563  //  log1 fprintf(Stderr,"Computing f-vector.\n");
564    ZVector fvector=this->fvector();
565    polymakeFile.writeCardinalVectorProperty("F_VECTOR",fvector);
566  //  log1 fprintf(Stderr,"Done computing f-vector.\n");
567
568    if(flags&FPF_boundedInfo)
569      {
570  //      log1 fprintf(Stderr,"Computing bounded f-vector.\n");
571        ZVector fvectorBounded=this->fvector(true);
572        polymakeFile.writeCardinalVectorProperty("F_VECTOR_BOUNDED",fvectorBounded);
573  //      log1 fprintf(Stderr,"Done computing bounded f-vector.\n");
574      }
575#if 0
576    {
577      Integer euler;
578      int mul=-1;
579      for(int i=0;i<fvector.size();i++,mul*=-1)euler+=Integer(mul)*fvector[i];
580      polymakeFile.writeCardinalProperty("MY_EULER",euler);
581    }
582#endif
583  //  log1 fprintf(Stderr,"Checking if complex is simplicial and pure.\n");
584    polymakeFile.writeCardinalProperty("SIMPLICIAL",isSimplicial());
585    polymakeFile.writeCardinalProperty("PURE",isPure());
586  //  log1 fprintf(Stderr,"Done checking.\n");
587
588    std::stringstream s;
589    polymakeFile.writeStream(s);
590    return s.str();
591
592    #if 0
593
594    if(flags&FPF_conesCompressed)
595    {
596  //    log1 fprintf(Stderr,"Producing list of cones up to symmetry.\n");
597      polymakeFile.writeStringProperty("CONES_ORBITS",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),false,flags&FPF_group,0,true,flags&FPF_tPlaneSort));
598  //    log1 fprintf(Stderr,"Done producing list of cones up to symmetry.\n");
599  //    log1 fprintf(Stderr,"Producing list of maximal cones up to symmetry.\n");
600      stringstream multiplicities;
601      polymakeFile.writeStringProperty("MAXIMAL_CONES_ORBITS",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),true,flags&FPF_group, &multiplicities,true,flags&FPF_tPlaneSort));
602      if(flags&FPF_multiplicities)polymakeFile.writeStringProperty("MULTIPLICITIES_ORBITS",multiplicities.str());
603  //    log1 fprintf(Stderr,"Done producing list of maximal cones up to symmetry.\n");
604    }
605
606    if(flags&FPF_conesExpanded)
607      {
608        if(flags&FPF_cones)
609          {
610  //          log1 fprintf(Stderr,"Producing list of cones.\n");
611            polymakeFile.writeStringProperty("CONES",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),false,flags&FPF_group,0,false,flags&FPF_tPlaneSort));
612  //          log1 fprintf(Stderr,"Done producing list of cones.\n");
613          }
614        if(flags&FPF_maximalCones)
615          {
616  //          log1 fprintf(Stderr,"Producing list of maximal cones.\n");
617            stringstream multiplicities;
618            polymakeFile.writeStringProperty("MAXIMAL_CONES",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),true,flags&FPF_group, &multiplicities,false,flags&FPF_tPlaneSort));
619            if(flags&FPF_multiplicities)polymakeFile.writeStringProperty("MULTIPLICITIES",multiplicities.str());
620  //          log1 fprintf(Stderr,"Done producing list of maximal cones.\n");
621          }
622      }
623  #endif
624    #if 0
625    if(flags&FPF_values)
626      {
627        {
628          ZMatrix values;
629          for(int i=0;i<linealitySpaceGenerators.getHeight();i++)
630            {
631              ZVector v(1);
632              v[0]=evaluatePiecewiseLinearFunction(linealitySpaceGenerators[i]);
633              values.appendRow(v);
634            }
635          polymakeFile.writeMatrixProperty("LINEALITY_VALUES",rowsToIntegerMatrix(values,1));
636        }
637        {
638          ZMatrix values;
639          for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++)
640            {
641              ZVector v(1);
642              v[0]=evaluatePiecewiseLinearFunction(*i);
643              values.push_back(v);
644            }
645          polymakeFile.writeMatrixProperty("RAY_VALUES",rowsToIntegerMatrix(values,1));
646        }
647      }
648  #endif
649
650
651  //  log1 fprintf(Stderr,"Producing final string for output.\n");
652  /*  stringstream s;
653    polymakeFile.writeStream(s);
654    string S=s.str();
655  //  log1 fprintf(Stderr,"Printing string.\n");
656    p->printString(S.c_str());
657  *///  log1 fprintf(Stderr,"Done printing string.\n");
658  }
659
660  ZCone SymmetricComplex::makeZCone(IntVector const &indices)const
661  {
662    ZMatrix generators(indices.size(),getAmbientDimension());
663    for(int i=0;i<indices.size();i++)
664      generators[i]=vertices[indices[i]];
665    return ZCone::givenByRays(generators,linealitySpace);
666  }
667}
Note: See TracBrowser for help on using the repository browser.