politopix  4.1.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Polytope_Rn.cpp
Go to the documentation of this file.
1 // politopix allows to make computations on polytopes such as finding vertices, intersecting, Minkowski sums, ...
2 // Copyright (C) 2011-2016 : Delos Vincent
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
19 // I2M (UMR CNRS 5295 / University of Bordeaux)
20 
21 #include <iostream>
22 #include <sstream>
23 #include <vector>
24 #include <math.h>
25 #include <boost/numeric/ublas/matrix.hpp>
26 #include <boost/numeric/ublas/matrix_proxy.hpp>
27 #include <boost/numeric/ublas/operation.hpp>
28 #include <boost/numeric/ublas/io.hpp>
29 #include "Rn.h"
30 #include "Polytope_Rn.h"
31 #include "IO_Polytope.h"
32 #include "DoubleDescription_Rn.h"
33 
34 
37 
38 public:
40 
47  const std::vector< HalfSpace_Rn* >& commonFacets,
48  const boost::shared_ptr<Generator_Rn>& gen,
49  unsigned int number=0) {
50  {for (unsigned int i=0; i<_HSPerPseudoNeighbours.size(); ++i) {
51  unsigned int nbCommonFacet=0;
52  {for (unsigned int j=0; j<_HSPerPseudoNeighbours[i].size(); ++j) {
53  {for (unsigned int k=0; k<commonFacets.size(); ++k) {
54  if (_HSPerPseudoNeighbours[i][j] == commonFacets[k]) {
55  ++nbCommonFacet;
56  if (nbCommonFacet == commonFacets.size()) {
57  // No need to do anything as the current generator set of
58  // half-spaces is included in the set number j.
59  return false;
60  }
61  else if (nbCommonFacet == _HSPerPseudoNeighbours[i].size()) {
62  // Substitute the old generator to be removed with the current one.
63  _HSPerPseudoNeighbours[i] = commonFacets;
64  _pseudoNeighboursNumber[i] = number;
65  _pseudoNeighbours[i] = gen;
66  return false;
67  }
68  }
69  }}
70  }}
71  }}
72  _pseudoNeighbours.push_back(gen);
73  _pseudoNeighboursNumber.push_back(number);
74  _HSPerPseudoNeighbours.push_back(commonFacets);
75  return true;
76  }
77 
79  void begin() {_iterator=0;}
80 
82  void next() {++_iterator;}
83 
85  bool end() {return (_iterator==_pseudoNeighbours.size());}
86 
89 
91  boost::shared_ptr<Generator_Rn> currentNeighbour() {return _pseudoNeighbours[_iterator];}
92 
94  void dump(std::ostream &ofs) {
95  ofs << "Real ngb:" << std::endl;
96  std::vector< std::vector< HalfSpace_Rn* > >::const_iterator ite;
97  for (ite=_HSPerPseudoNeighbours.begin(); ite!=_HSPerPseudoNeighbours.end(); ++ite) {
98  std::copy((*ite).begin(), (*ite).end(), std::ostream_iterator< HalfSpace_Rn* >(ofs, " ") );
99  ofs << std::endl;
100  }
101  }
102 
103 protected:
105  unsigned int _iterator;
107  std::vector< unsigned int > _pseudoNeighboursNumber;
109  std::vector< boost::shared_ptr<Generator_Rn> > _pseudoNeighbours;
111  std::vector< std::vector< HalfSpace_Rn* > > _HSPerPseudoNeighbours;
112 };
113 
114 
116  // Check all edges, built from neighbor generators and topological data, are on frontier and not inside the polytope.
117  std::cout << "Check edges.......... ";
118  unsigned int RnDIM= this->dimension();
119  bool checkEdgesOK = true;
120  {for (unsigned int i=0; i<numberOfGenerators(); i++) {
121  boost::shared_ptr<Generator_Rn> V1 = _listOfGenerators[i];
122  for (unsigned int j=0; j<numberOfGenerators(); j++) {
123  boost::shared_ptr<Generator_Rn> V2 = _listOfGenerators[j];
124  std::vector< boost::shared_ptr<HalfSpace_Rn> > commonFacets;
125  if (V1 != V2 && checkNeighbours(V1, V2, commonFacets) == true) {
126  // Build the edge with V1 & V2 and check it is inside all facets.
127  std::vector<double> edge(RnDIM);
128  for (unsigned int k=0; k<RnDIM; k++)
129  edge[k] = V1->getCoordinate(k) - V2->getCoordinate(k);
130  unsigned int countFacets = 0;
131  double scalarProduct = 0.;
132  for (unsigned int l=0; l<commonFacets.size(); l++) {
133  for (unsigned int n=0; n<RnDIM; n++)
134  scalarProduct = scalarProduct + edge[n]*commonFacets[l]->getCoefficient(n);
135  if (scalarProduct < -Rn::getTolerance() || scalarProduct > Rn::getTolerance()) {
136  std::cout << "\t### Edge for generators " << i << " and " << j << " not on facet (";
137  {for (unsigned int jj=0; jj<RnDIM; jj++) {
138  std::cout << commonFacets[l]->getCoefficient(jj) << " ";
139  if (jj == RnDIM-1)
140  std::cout << commonFacets[l]->getSideAsText() << " " << commonFacets[l]->getConstant();
141  }}
142  std::cout << ") " << std::endl;
143  checkEdgesOK = false;
144  }
145  else
146  countFacets++;
147  }
148  // For polytopes only.
149  if (countFacets < RnDIM-1) {
150  std::cout << "\t### Edge for generators " << i << " and " << j << " has not enough facets" << std::endl;
151  checkEdgesOK = false;
152  }
153  }
154  }
155  }}
156  if (checkEdgesOK == true)
157  std::cout << "OK" << std::endl;
158  return checkEdgesOK;
159 }
160 
163  double MIN =-M;
164  double MAX = (2*dimension()-1)*M;
165  unsigned int dim = dimension();
166  unsigned int currentNumberOfFacets = (unsigned int)dimension()+1;
167  unsigned int currentNumberOfGenerators = (unsigned int)dimension()+1;
168  //std::cout << "Number of generators = " << currentNumberOfGenerators << std::endl;
169 
170  // Fill the data structure with blank Generators, 4 in dim 2, 8 in dim 3, ...
171  {for (unsigned int vtx_count=0; vtx_count<currentNumberOfGenerators; vtx_count++) {
172  boost::shared_ptr<Generator_Rn> VX;
173  VX.reset(new Generator_Rn(dim));
174  addGenerator(VX);
175  }}
176  // Create the simplex generators (MIN, MIN, ..., MAX, ..., MIN) where MAX
177  // moves from 0 to (n-1) and the last vertex is (MIN, ..., MIN).
178  {for (unsigned int coord_count=0; coord_count<dim; coord_count++) {
179  {for (unsigned int vtx_count=0; vtx_count<currentNumberOfGenerators; vtx_count++) {
180  //vtx_count==currentNumberOfGenerators-1 => this vertex is the corner i.e. (MIN, ..., MIN)
181  if (vtx_count==coord_count && vtx_count<currentNumberOfGenerators-1)
182  getGenerator(vtx_count)->setCoordinate(coord_count, MAX);
183  else
184  getGenerator(vtx_count)->setCoordinate(coord_count, MIN);
185  }}
186  }}
187  // Create the simplex array of facets excepted the oblic one, for the moment.
188  std::vector< boost::shared_ptr<HalfSpace_Rn> > supportFacets;
189  // M + xi >= 0.
190  {for (unsigned int facet_count=0; facet_count<currentNumberOfFacets-1; facet_count++) {
191  boost::shared_ptr<HalfSpace_Rn> HalfSp(new HalfSpace_Rn(dim));
192  {for (unsigned int coord_count=0; coord_count<dim; coord_count++) {
193  if (facet_count == coord_count)
194  HalfSp->setCoefficient(coord_count, 1.);
195  else
196  HalfSp->setCoefficient(coord_count, 0.);
197  }}
198  HalfSp->setConstant(M);
199  supportFacets.push_back(HalfSp);
200  // The first generator is the corner so it has
201  // to contain all the perpendicular half-spaces.
202  getGenerator(currentNumberOfGenerators-1)->setFacet(HalfSp);
203  }}
204  // Oblic half-space (Rn::getDimension()*M, -1., ..., -1.)
205  boost::shared_ptr<HalfSpace_Rn> oblicHalfSp(new HalfSpace_Rn(dim));
206  {for (unsigned int coord_count=0; coord_count<dim; coord_count++) {
207  oblicHalfSp->setCoefficient(coord_count, -1.);
208  }}
209  oblicHalfSp->setConstant(dimension()*M);
210  supportFacets.push_back(oblicHalfSp);
212  {for (iteH.begin(); iteH.end()!=true; iteH.next()) {
213  supportFacets.push_back(iteH.current());
214  }}
216  std::vector< boost::shared_ptr<HalfSpace_Rn> >::const_iterator itF;
217  {for (itF=supportFacets.begin(); itF!=supportFacets.end();++itF) {
219  }}
220  // Make connections between the generators excepted the corner (already treated).
221  {for (unsigned int vtx_count1=0; vtx_count1<currentNumberOfGenerators-1; vtx_count1++) {
222  boost::shared_ptr<Generator_Rn> VX1 = getGenerator(vtx_count1);
223  VX1->setFacet(oblicHalfSp);
224  {for (unsigned int coord_count=0; coord_count<dim; coord_count++) {
225  if (VX1->getCoordinate(coord_count) == MIN) {
226  VX1->setFacet(_listOfHalfSpaces[coord_count]);
227  }
228  }}
229  }}
230  //std::string FileOut("simplex.ptop");
231  //boost::shared_ptr<Polytope_Rn> A(this);
232  //IO_Polytope::save(FileOut, A);
233  //exit(0);
234 }
235 
238  double MAX = M;
239  unsigned int dim = dimension();
240  unsigned int currentNumberOfGenerators = (unsigned int)pow(static_cast<double>(2), static_cast<int>(dim));
241  //std::cout << "Number of generators = " << currentNumberOfGenerators << std::endl;
242 
243  // Fill the data structure with blank Generators, 4 in dim 2, 8 in dim 3, ...
244  for (unsigned int vtx_count=0; vtx_count<currentNumberOfGenerators; vtx_count++) {
245  boost::shared_ptr<Generator_Rn> VX;
246  VX.reset(new Generator_Rn(dim));
247  addGenerator(VX);
248  }
249  // Create the cube generators.
250  for (unsigned int coord_count=0; coord_count<dim; coord_count++) {
251  int counter = 0;
252  for (unsigned int vtx_count=0; vtx_count<currentNumberOfGenerators; vtx_count++) {
253  if (counter >= pow(static_cast<double>(2), static_cast<int>(coord_count))) {
254  MAX = -1. * MAX;
255  counter = 0;
256  }
257  getGenerator(vtx_count)->setCoordinate(coord_count, MAX);
258  counter++;
259  }
260  }
261  // Create the cube array of facets.
262  std::vector< boost::shared_ptr<HalfSpace_Rn> > supportFacets;
263  // xi < M
264  for (unsigned int facet_count=0; facet_count<dim; facet_count++) {
265  boost::shared_ptr<HalfSpace_Rn> HalfSp(new HalfSpace_Rn(dim));
266  for (unsigned int coord_count=0; coord_count<dim; coord_count++) {
267  if (facet_count == coord_count)
268  HalfSp->setCoefficient(coord_count, -1.);
269  else
270  HalfSp->setCoefficient(coord_count, 0.);
271  }
272  HalfSp->setConstant(M);
273  supportFacets.push_back(HalfSp);
274  }
275  // xi > -M
276  for (unsigned int facet_count=0; facet_count<dim; facet_count++) {
277  boost::shared_ptr<HalfSpace_Rn> HalfSp(new HalfSpace_Rn(dim));
278  for (unsigned int coord_count=0; coord_count<dim; coord_count++) {
279  if (facet_count == coord_count)
280  HalfSp->setCoefficient(coord_count, 1.);
281  else
282  HalfSp->setCoefficient(coord_count, 0.);
283  }
284  HalfSp->setConstant(M);
285  supportFacets.push_back(HalfSp);
286  }
288  {for (iteH.begin(); iteH.end()!=true; iteH.next()) {
289  supportFacets.push_back(iteH.current());
290  }}
292  std::vector< boost::shared_ptr<HalfSpace_Rn> >::const_iterator itF;
293  {for (itF=supportFacets.begin(); itF!=supportFacets.end();++itF) {
295  }}
296  // Make connections between the generators.
297  for (unsigned int vtx_count1=0; vtx_count1<currentNumberOfGenerators; vtx_count1++) {
298  boost::shared_ptr<Generator_Rn> VX1 = getGenerator(vtx_count1);
299  for (unsigned int coord_count=0; coord_count<dim; coord_count++) {
300  if (VX1->getCoordinate(coord_count) == M)
301  VX1->setFacet(_listOfHalfSpaces[coord_count]);
302  else if (VX1->getCoordinate(coord_count) == -M)
303  VX1->setFacet(_listOfHalfSpaces[coord_count+dim]);
304  }
305  }
306 }
307 
310  const boost::shared_ptr<Generator_Rn_SD>& out,
311  const boost::shared_ptr<Generator_Rn_SD>& in,
312  boost::shared_ptr<Generator_Rn_SD> newV, double ay, double az, double b) const {
313  // Formula for polytopes.
314  double t = (-b-az) / (ay-az);
315  //for (unsigned int k=0; k<Rn::getDimension(); k++) {
316  //double yi = out->getCoordinate(k);
317  //double zi = in->getCoordinate(k);
318  //newV->setCoordinate(k, zi+(yi-zi)*t);
319  //}
320  newV->makeDiff(out, in);
321  newV->makeCoefSum(in, newV, 1., t);
322 }
323 
324 bool Polytope_Rn::checkEqualityOfVertices(const boost::shared_ptr<Polytope_Rn>& B, bool printOnScreen) const {
325  double RnDIM = Rn::getDimension();
326  double TOL2 = Rn::getTolerance()*Rn::getTolerance();
327  std::vector<bool> vtxOfA(numberOfGenerators());
328  std::vector<bool> vtxOfB(B->numberOfGenerators());
329  for (unsigned int i=0; i<vtxOfA.size(); ++i)
330  vtxOfA[i] = false;
331  for (unsigned int i=0; i<vtxOfB.size(); ++i)
332  vtxOfB[i] = false;
335  {for (iteGN_A.begin(); iteGN_A.end()!=true; iteGN_A.next()) {
336  {for (iteGN_B.begin(); iteGN_B.end()!=true; iteGN_B.next()) {
337  if (iteGN_A.current()->isEqual2(iteGN_B.current(), RnDIM, TOL2)) {
338  vtxOfA[ iteGN_A.currentIteratorNumber() ] = true;
339  vtxOfB[ iteGN_B.currentIteratorNumber() ] = true;
340  }
341  }}
342  }}
343  bool AinsideB = true, BinsideA = true;
344  {for (unsigned int i=0; i<vtxOfA.size(); ++i) {
345  if (vtxOfA[i] == false) {
346  AinsideB = false;
347  break;
348  }
349  }}
350  {for (unsigned int i=0; i<vtxOfB.size(); ++i) {
351  if (vtxOfB[i] == false) {
352  BinsideA = false;
353  break;
354  }
355  }}
356  if (printOnScreen == true) {
357  if (AinsideB == true)
358  std::cout << "The set of vertices of A in included in the set of vertices of B." << std::endl;
359  if (BinsideA == true)
360  std::cout << "The set of vertices of B in included in the set of vertices of A." << std::endl;
361  }
362 
363  return (AinsideB && BinsideA);
364 }
365 
366 
367 boost::shared_ptr<PolyhedralCone_Rn> Polytope_Rn::getPrimalCone(unsigned int u) const throw (std::out_of_range) {
368  if (u >= numberOfGenerators())
369  throw std::out_of_range("Polytope_Rn::getPrimalCone() index out of range");
370 
371  boost::shared_ptr<PolyhedralCone_Rn> primalCone;
372  boost::shared_ptr<Generator_Rn> vx1 = getGenerator(u);
374  // Split the polytope into its primal polyhedral cones //
376  primalCone.reset(new PolyhedralCone_Rn());
377  // Insert all half-spaces connected to the current vertex into the primal cone.
378  for (unsigned int i=0; i<vx1->numberOfFacets(); i++) {
379  primalCone->addHalfSpace(vx1->getFacet(i));
380  }
381  for (unsigned int v=0; v<numberOfGenerators(); v++) {
382  if (u != v) {
383  boost::shared_ptr<Generator_Rn> vx2 = getGenerator(v);
384  std::vector< boost::shared_ptr<HalfSpace_Rn> > commonFacets;
385  if (checkNeighbours(vx1, vx2, commonFacets) == true) {
386  // Build the edge.
387  boost::shared_ptr<Generator_Rn> edge12(new Generator_Rn(dimension()));
388  for (unsigned int k=0; k<dimension(); k++) {
389  edge12->setCoordinate(k, vx2->getCoordinate(k)-vx1->getCoordinate(k));
390  }
391  // Build the facet list.
392  for (unsigned int j=0; j<commonFacets.size(); j++) {
393  boost::shared_ptr<HalfSpace_Rn> Fj = commonFacets[j];
394  edge12->setFacet(Fj);
395  }
396  // Insert the edge into the primal cone.
397  primalCone->addGenerator(edge12);
398  }
399  }
400  }
401  return primalCone;
402 }
403 
404 boost::shared_ptr<PolyhedralCone_Rn> Polytope_Rn::getPrimalCone(const boost::shared_ptr<Generator_Rn>& vx1) const {
405  unsigned int RnDIM=dimension();
406  boost::shared_ptr<PolyhedralCone_Rn> primalCone;
408  // Split the polytope into its primal polyhedral cones //
410  primalCone.reset(new PolyhedralCone_Rn());
411  // Insert all half-spaces connected to the current vertex into the primal cone.
412  for (unsigned int i=0; i<vx1->numberOfFacets(); i++) {
413  primalCone->addHalfSpace(vx1->getFacet(i));
414  }
415  RealNeighbours rn;
417  {for (iteGN_A.begin(); iteGN_A.end()!=true; iteGN_A.next()) {
418  boost::shared_ptr<Generator_Rn> vx2 = iteGN_A.current();
419  if (vx1 != vx2) {
420  std::vector< HalfSpace_Rn* > commonPFacets;
421  // Create an empty set for the signature.
422  std::set< boost::shared_ptr<HalfSpace_Rn> > listOfRedundantHS;
423  if (checkNeighboursWithHSnumbers(vx1, vx2, commonPFacets, listOfRedundantHS) == true) {
424  rn.addNeighbour(commonPFacets, vx2);
425  }
426  }
427  }}
428  //rn.dump(std::cout);
429  for (rn.begin(); rn.end()!=true; rn.next()) {
430  boost::shared_ptr<Generator_Rn> vx2 = rn.currentNeighbour();
431  // Build the edge.
432  boost::shared_ptr<Generator_Rn> edge12(new Generator_Rn(RnDIM));
433  edge12->makeDiff(vx2, vx1);
434  // Build the facet list.
435  std::vector< boost::shared_ptr<HalfSpace_Rn> > commonFacets;
436  // Get facets.
437  checkNeighbours(vx1, vx2, commonFacets);
438  for (unsigned int j=0; j<commonFacets.size(); ++j) {
439  boost::shared_ptr<HalfSpace_Rn> Fj = commonFacets[j];
440  edge12->setFacet(Fj);
441  }
442  // Insert the edge into the primal cone.
443  primalCone->addGenerator(edge12);
444  }
445  return primalCone;
446 }
listOfGeometricObjects< boost::shared_ptr< HalfSpace_Rn > > & getListOfHalfSpaces()
Return the list of half-spaces.
const listOfGeometricObjects< boost::shared_ptr< Generator_Rn > > & getListOfGenerators() const
Return the list of generators.
Class dedicated to degeneration processing when looking for neighbors.
Definition: Polytope_Rn.cpp:36
unsigned int _iterator
A runner to iterate through the list of genuine neighbors.
virtual void createTruncatedGenerator(const boost::shared_ptr< Generator_Rn_SD > &in, const boost::shared_ptr< Generator_Rn_SD > &out, boost::shared_ptr< Generator_Rn_SD > newV, double ay, double az, double b=0.) const
This is the intersection vertex in the truncating algorithm, defined by the intersection between an e...
const boost::shared_ptr< Generator_Rn > & getGenerator(unsigned int i) const
Return the i-th generator.
boost::shared_ptr< Generator_Rn > currentNeighbour()
Iterator function.
Definition: Polytope_Rn.cpp:91
bool checkEqualityOfVertices(const boost::shared_ptr< Polytope_Rn > &B, bool printOnScreen=false) const
Check whether two V-polytopes are identical Check whether the sets of vertices of A and B are equal...
int currentIteratorNumber() const
Return the current position in the list.
A half-space whose frontier is a linear (n-1) dimension space. _constant + _coefficients[0].x1 + ... + _coefficients[n-1].xn >= 0.
Definition: HalfSpace_Rn.h:37
Model a polyhedral cone using its two equivalent definitions : the convex hull and the half-space int...
bool checkNeighbours(const boost::shared_ptr< Generator_Rn > &V1, const boost::shared_ptr< Generator_Rn > &V2, std::vector< boost::shared_ptr< HalfSpace_Rn > > &commonFacets, const std::set< boost::shared_ptr< HalfSpace_Rn > > &listOfRedundantHS) const
boost::shared_ptr< PolyhedralCone_Rn > getPrimalCone(unsigned int i) const
const GEOMETRIC_OBJECT current()
Return the current geometric element.
std::vector< unsigned int > _pseudoNeighboursNumber
The generator numbers in a global list.
listOfGeometricObjects< boost::shared_ptr< Generator_Rn > > _listOfGenerators
The convex hull of connected points.
void begin()
Move the iterator at the beginning of the list.
void dump(std::ostream &ofs)
Display the content on the stream passed as an argument.
Definition: Polytope_Rn.cpp:94
unsigned int numberOfGenerators() const
Give the total number of generators.
static polito_EXPORT double getTolerance()
Give the minimum distance between two points.
Definition: Rn.cpp:31
bool end() const
Tell whether we have reached the end of the list.
bool addNeighbour(const std::vector< HalfSpace_Rn * > &commonFacets, const boost::shared_ptr< Generator_Rn > &gen, unsigned int number=0)
Tell whether a pseudo neighbor is a genuine one comparing set of half-spaces.
Definition: Polytope_Rn.cpp:46
std::vector< std::vector< HalfSpace_Rn * > > _HSPerPseudoNeighbours
For each generator, store all raw pointers on their corresponding half-spaces.
void begin()
Iterator function.
Definition: Polytope_Rn.cpp:79
std::vector< boost::shared_ptr< Generator_Rn > > _pseudoNeighbours
The generator smart pointer.
static polito_EXPORT unsigned int getDimension()
Return the dimension of the cartesian space we work in.
Definition: Rn.cpp:29
A n-coordinates generator, which can be a vertex or an edge whether it is contained by a polytope or ...
Definition: Generator_Rn.h:38
virtual void createBoundingBox(double M)
Initialize the truncating algorithm building a M-sized bounding box around the polytope.
bool end()
Iterator function.
Definition: Polytope_Rn.cpp:85
This class is designed to run the list of all geometric objects representing a polytope.
virtual bool checkEdges() const
Always true in the polyhedral cone case.
void next()
Move the iterator one step forward.
virtual unsigned int dimension() const
Return the space dimension.
listOfGeometricObjects< boost::shared_ptr< HalfSpace_Rn > > _listOfHalfSpaces
The list of half-spaces defining the polytope.
bool checkNeighboursWithHSnumbers(const boost::shared_ptr< Generator_Rn > &V1, const boost::shared_ptr< Generator_Rn > &V2, std::vector< HalfSpace_Rn * > &commonFacets, const std::set< boost::shared_ptr< HalfSpace_Rn > > &listOfRedundantHS, unsigned int topologicalCode=1) const
Check for polytopes that vertices share (n-1) facets. For polyhedral cones, it must check that vector...
virtual void createBoundingSimplex(double M)
Initialize the truncating algorithm building a M-sized simplex around the polytope.
void clear()
Clear the whole list.
void next()
Iterator function.
Definition: Polytope_Rn.cpp:82
void push_back(const GEOMETRIC_OBJECT &gn)
Include a new half space in the list.
unsigned int currentGeneratorNumber()
Iterator function.
Definition: Polytope_Rn.cpp:88
PolyhedralCone_Rn()
Constructor.
void addGenerator(boost::shared_ptr< Generator_Rn > vx)
Add the given generator.