politopix  4.1.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
PolyhedralCone_Rn.h
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 #ifndef POLYHEDRALCONE_Rn
22 #define POLYHEDRALCONE_Rn
23 
24 #include <boost/numeric/ublas/io.hpp>
25 #include <boost/shared_ptr.hpp>
26 #include <stdexcept>
27 #include <exception>
28 #include <iterator>
29 #include <numeric>
30 #include <vector>
31 #include <set>
32 #include "polito_Export.h"
34 #include "Neighbours_Rn.h"
35 #include "Generator_Rn.h"
36 #include "HalfSpace_Rn.h"
37 #include "Rn.h"
38 
39 using namespace boost::numeric::ublas;
40 
41 
46  friend class lexIteratorOfListOfHalfSpaces;
47  friend class constIteratorOfListOfHalfSpaces;
48 
49  public:
52 
55  _listOfHalfSpaces = A._listOfHalfSpaces;
56  _listOfGenerators = A._listOfGenerators;
57  }
58 
60  virtual ~PolyhedralCone_Rn() {}
61 
63  virtual unsigned int dimension() const {
64  if (numberOfHalfSpaces()==0 && numberOfGenerators()==0)
65  return Rn::getDimension();
66  else if (numberOfGenerators()==0) {
68  const boost::shared_ptr<HalfSpace_Rn>& currentHalfSpace = iteHS.current();
69  return currentHalfSpace->dimension();
70  }
71  else {
73  const boost::shared_ptr<Generator_Rn>& currentGenerator = iteGN.current();
74  return currentGenerator->dimension();
75  }
76  }
77 
79  virtual bool isBounded() const {return false;}
80 
82  virtual unsigned int neigbourhoodCondition() const {return (dimension()-2);}
83 
85  virtual unsigned int numberOfGeneratorsPerFacet() const {return (dimension()-1);}
86 
88  void reset() {_listOfHalfSpaces.clear(); _listOfGenerators.clear();}
89 
90  // HALF-SPACES
91 
93  unsigned int numberOfHalfSpaces() const {return _listOfHalfSpaces.size();}
94 
96  boost::shared_ptr<HalfSpace_Rn> addHalfSpace(boost::shared_ptr<HalfSpace_Rn> hs, bool check=false);
97 
99  void removeHalfSpaceFromListAndGenerators(const boost::shared_ptr<HalfSpace_Rn>& hs) throw (std::invalid_argument);
100 
102  void removeHalfSpace(unsigned int j) {_listOfHalfSpaces.removeGeometricObject(j);}
103 
105  void removeHalfSpaces(const std::set< boost::shared_ptr<HalfSpace_Rn> >& setOfRedundantHS) {
106  _listOfHalfSpaces.removeGeometricObjects( setOfRedundantHS );
107  }
108 
110  unsigned int getHalfSpaceNumber(const boost::shared_ptr<HalfSpace_Rn>& F) const throw (std::out_of_range) {
111  unsigned int index;
112  try {
113  index = _listOfHalfSpaces.find(F);
114  }
115  catch(std::out_of_range& excep) {
116  std::string ex(excep.what());
117  ex += std::string(" : Catch in PolyhedralCone_Rn::getHalfSpaceNumber()");
118  throw std::out_of_range(ex);
119  }
120  return index;
121  }
122 
124  const boost::shared_ptr<HalfSpace_Rn>& getHalfSpace(unsigned int i) const throw (std::out_of_range);
125 
128 
131 
132 
133  // CONVEX HULL
134 
136  unsigned int numberOfGenerators() const {return _listOfGenerators.size();}
137 
139  void addGenerator(boost::shared_ptr<Generator_Rn> vx) {_listOfGenerators.push_back(vx);}
140 
142  const boost::shared_ptr<Generator_Rn>& getGenerator(unsigned int i) const throw (std::out_of_range);
143 
145  unsigned int getGeneratorNumber(boost::shared_ptr<Generator_Rn> G) const throw (std::out_of_range,std::invalid_argument);
146 
149 
150  unsigned int getListOfGeneratorsSD(std::vector< boost::shared_ptr<Generator_Rn_SD> >& currentListOfGeneratorsSD) {
151  unsigned int generatorNumber=0;
153  {for (iteGN.begin(); iteGN.end()!=true; iteGN.next()) {
154  boost::shared_ptr<Generator_Rn_SD>
155  currentGeneratorSD(new Generator_Rn_SD(*iteGN.current(), generatorNumber, Generator_Rn_SD::UNCHANGED));
156  {for (unsigned int ii=0; ii<iteGN.current()->numberOfFacets(); ii++) {
157  unsigned int fctNumber = getHalfSpaceNumber( iteGN.current()->getFacet(ii) );
158  currentGeneratorSD->setFacet(fctNumber);
159  }}
160  currentGeneratorSD->orderFacets();
161  currentListOfGeneratorsSD.push_back(currentGeneratorSD);
162  ++generatorNumber;
163  }}
164  return generatorNumber;
165  }
166 
168  void setListOfGeneratorsSD(const std::vector< boost::shared_ptr<Generator_Rn_SD> >& gnList) {
170  std::vector< boost::shared_ptr<Generator_Rn_SD> >::const_iterator iteGN;
171  {for (iteGN=gnList.begin(); iteGN!=gnList.end(); ++iteGN) {
172  if ((*iteGN)->getStatus() == Generator_Rn_SD::CREATED ||
173  (*iteGN)->getStatus() == Generator_Rn_SD::CREATED_AND_MODIFIED) {
174  boost::shared_ptr<Generator_Rn> currentGenerator = (*iteGN)->makeGenerator_Rn();
175  {for (unsigned int ii=0; ii<(*iteGN)->numberOfFacets(); ii++) {
176  currentGenerator->setFacet( _listOfHalfSpaces[(*iteGN)->getFacet(ii)] );
177  }}
178  listOfGenerators.push_back( currentGenerator );
179  }
180  else if ((*iteGN)->getStatus() == Generator_Rn_SD::MODIFIED) {
181  // Substitute all old half-spaces with the new ones.
182  unsigned int nbGN = (*iteGN)->getGeneratorNumber();
183  boost::shared_ptr<Generator_Rn> currentGenerator = _listOfGenerators[nbGN];
184  currentGenerator->clearFacets();
185  {for (unsigned int ii=0; ii<(*iteGN)->numberOfFacets(); ii++) {
186  currentGenerator->setFacet( _listOfHalfSpaces[(*iteGN)->getFacet(ii)] );
187  }}
188  listOfGenerators.push_back(_listOfGenerators[nbGN]);
189  }
190  else if ((*iteGN)->getStatus() == Generator_Rn_SD::UNCHANGED) {
191  // Substitute all old half-spaces with the new ones.
192  unsigned int nbGN = (*iteGN)->getGeneratorNumber();
193  listOfGenerators.push_back(_listOfGenerators[nbGN]);
194  }
195  // If it was deleted we obviously don't need it.
196  }}
197  _listOfGenerators.clear();
198  _listOfGenerators = listOfGenerators;
199  }
200 
201  void relocateGenerators();
202 
204  void setListOfGenerators(const listOfGeometricObjects< boost::shared_ptr<Generator_Rn> >& gnList) {_listOfGenerators = gnList;}
205 
206 
207  // CHECK POLYHEDRON
208 
215  bool checkNeighbours(const boost::shared_ptr<Generator_Rn>& V1,
216  const boost::shared_ptr<Generator_Rn>& V2,
217  std::vector< boost::shared_ptr<HalfSpace_Rn> >& commonFacets,
218  const std::set< boost::shared_ptr<HalfSpace_Rn> >& listOfRedundantHS) const throw (std::invalid_argument) {
219  unsigned int sameHyperplane=0;
220  for (unsigned int i=0; i<V1->numberOfFacets(); i++) {
221  for (unsigned int j=0; j<V2->numberOfFacets(); j++) {
222  if (V1->getRawFacet(i)==V2->getRawFacet(j) && listOfRedundantHS.find(V1->getFacet(i))==listOfRedundantHS.end()) {
223  // Check the facet is not declared redundant !
224  sameHyperplane++;
225  commonFacets.push_back(V1->getFacet(i));
226  }
227  }
228  }
229  // For polyhedral cones it is Rn::getDimension()-1, for polytopes it is Rn::getDimension()-2.
230  if (sameHyperplane >= neigbourhoodCondition())
231  return true;
232  return false;
233  }
234 
238  bool isIncluded(const boost::shared_ptr<PolyhedralCone_Rn>& B) const;
239 
246  bool checkNeighbours(const boost::shared_ptr<Generator_Rn>& V1,
247  const boost::shared_ptr<Generator_Rn>& V2,
248  std::vector< boost::shared_ptr<HalfSpace_Rn> >& commonFacets,
249  unsigned int topologicalCode=1) const throw (std::invalid_argument) {
250  unsigned int sameHyperplane=0;
251  for (unsigned int i=0; i<V1->numberOfFacets(); i++) {
252  for (unsigned int j=0; j<V2->numberOfFacets(); j++) {
253  if (V1->getRawFacet(i) == V2->getRawFacet(j)) {
254  // Check the facet is not declared redundant !
255  sameHyperplane++;
256  commonFacets.push_back(V1->getFacet(i));
257  }
258  }
259  }
260  // For polyhedral cones neigbourhoodCondition() is Rn::getDimension()-1, for polytopes it is Rn::getDimension()-2.
261  if (sameHyperplane >= neigbourhoodCondition()-topologicalCode+1) {
262  return true;
263  }
264  return false;
265  }
266 
274  const boost::shared_ptr<Generator_Rn>& V1,
275  const boost::shared_ptr<Generator_Rn>& V2,
276  std::vector< HalfSpace_Rn* >& commonFacets,
277  unsigned int topologicalCode=1) const throw (std::invalid_argument) {
278  unsigned int sameHyperplane=0;
279  for (unsigned int i=0; i<V1->numberOfFacets(); ++i) {
280  for (unsigned int j=0; j<V2->numberOfFacets(); ++j) {
281  if (V1->getRawFacet(i)==V2->getRawFacet(j)) {
282  // Check the facet is not declared redundant !
283  sameHyperplane++;
284  commonFacets.push_back(V1->getRawFacet(i));
285  }
286  }
287  }
288  // For polyhedral cones neigbourhoodCondition() is Rn::getDimension()-1, for polytopes it is Rn::getDimension()-2.
289  if (sameHyperplane >= neigbourhoodCondition()-topologicalCode+1) {
290  return true;
291  }
292  return false;
293  }
294 
300  const boost::shared_ptr<Generator_Rn_SD>& genIn,
301  const boost::shared_ptr<Generator_Rn_SD>& genOut,
302  std::vector< unsigned int >& commonFacets) {
303  // Compute the intersection on sorted lists of facets.
304  std::set_intersection(genIn->facetsBegin(), genIn->facetsEnd(), genOut->facetsBegin(), genOut->facetsEnd(),
305  std::inserter(commonFacets, commonFacets.end()));
306  // For polyhedral cones neigbourhoodCondition() is Rn::getDimension()-1, for polytopes it is Rn::getDimension()-2.
307  if (commonFacets.size() >= neigbourhoodCondition())
308  return true;
309 
310  return false;
311  }
312 
313 
322  const boost::shared_ptr<Generator_Rn>& V1,
323  const boost::shared_ptr<Generator_Rn>& V2,
324  std::vector< HalfSpace_Rn* >& commonFacets,
325  const std::set< boost::shared_ptr<HalfSpace_Rn> >& listOfRedundantHS,
326  unsigned int topologicalCode=1) const throw (std::invalid_argument) {
327  unsigned int sameHyperplane=0;
328  for (unsigned int i=0; i<V1->numberOfFacets(); ++i) {
329  for (unsigned int j=0; j<V2->numberOfFacets(); ++j) {
330  if (V1->getRawFacet(i)==V2->getRawFacet(j) &&
331  listOfRedundantHS.find(V1->getFacet(i))==listOfRedundantHS.end()) {
332  // Check the facet is not declared redundant !
333  sameHyperplane++;
334  commonFacets.push_back(V1->getRawFacet(i));
335  }
336  }
337  }
338  // For polyhedral cones neigbourhoodCondition() is Rn::getDimension()-1, for polytopes it is Rn::getDimension()-2.
339  if (sameHyperplane >= neigbourhoodCondition()-topologicalCode+1) {
340  return true;
341  }
342  return false;
343  }
344 
348  void fillNeighbourMatrix(std::vector< std::vector<unsigned int> >& neighboursA, unsigned int topologicalCode=1) const throw (std::out_of_range) {
349  if (neighboursA.size() != numberOfGenerators()) {
350  std::string errorMessage("PolyhedralCone_Rn::fillNeighbourMatrix wrong matrix size");
351  throw std::out_of_range(errorMessage);
352  }
354  //Neighbours_Rn newGeneratorsTool;
355  {for (iteGN_A1.begin(); iteGN_A1.end()!=true; iteGN_A1.next()) {
356  const boost::shared_ptr<Generator_Rn>& v1_A = iteGN_A1.current();
358  {for (iteGN_A2.begin(); iteGN_A2.end()!=true; iteGN_A2.next()) {
359  const boost::shared_ptr<Generator_Rn>& v2_A = iteGN_A2.current();
360  std::vector< HalfSpace_Rn* > commonFacets;
361  if (v1_A != v2_A) {
362  //neighboursA(iteGN_A1.currentIteratorNumber(), iteGN_A2.currentIteratorNumber()) =
363  if (checkNeighbours(v1_A, v2_A, commonFacets, topologicalCode) == true) {
364  neighboursA[iteGN_A1.currentIteratorNumber()].push_back(iteGN_A2.currentIteratorNumber());
365  //newGeneratorsTool.addGenerator(
366  // commonFacets,
367  // v1_A,
368  // v2_A,
369  // iteGN_A1.currentIteratorNumber(),
370  // iteGN_A2.currentIteratorNumber());
371  }
372  }
373  else {
374  //std::cout << "v1=" << iteGN_A1.currentIteratorNumber() << ", v2=" << iteGN_A2.currentIteratorNumber() << std::endl;
375  neighboursA[iteGN_A1.currentIteratorNumber()].push_back(iteGN_A2.currentIteratorNumber());
376  }
377  }}
378  }}
379  //@@
380  //newGeneratorsTool.dump(std::cout);
381  //for (newGeneratorsTool.begin(); newGeneratorsTool.end()!=true; newGeneratorsTool.next()) {
382  // neighboursA(newGeneratorsTool.currentGenInNumber(), newGeneratorsTool.currentGenOutNumber()) = 1;
383  // neighboursA(newGeneratorsTool.currentGenOutNumber(), newGeneratorsTool.currentGenInNumber()) = 1;
384  //}
385  }
386 
393  virtual bool checkTopologyAndGeometry() const {
394  std::cout << "# Dimension NumberOfHalfspaces NumberOfGenerators" << std::endl;
395  std::cout << dimension() << " " << numberOfHalfSpaces() << " " << numberOfGenerators() << std::endl;
396 
397  // Check that all generators have at least (n-1) facets in the case of a polyhedral cone and are inside the H-representation.
398  bool checkGeneratorsOK = checkGenerators(_listOfGenerators, _listOfHalfSpaces);
399 
400  // Check that all facets have at least (n-1) generators in the case of a polyhedral cone.
401  bool checkFacetsOK = checkFacets();
402 
403  return (checkGeneratorsOK==true && checkFacetsOK==true);
404  }
405 
408  HalfSpace_Rn::State checkPoint(const Point_Rn& thisPoint) const;
409 
412  HalfSpace_Rn::State checkPoint(
413  const boost::shared_ptr<Generator_Rn>& point,
414  const boost::shared_ptr<HalfSpace_Rn>& halfSpace,
415  double halfSpaceNorm) const;
416 
421  bool checkDuplicateGenerators(unsigned int& a, unsigned int& b);
422 
424  void checkGenerator(unsigned int vtxNumber, std::ostream &this_ostream) const throw (std::out_of_range) {
425  if (vtxNumber >= _listOfGenerators.size())
426  throw std::out_of_range("PolyhedralCone_Rn::checkGenerator(unsigned int fctNumber, std::ostream &this_ostream) inadequate generator number!");
427  this_ostream.precision(15);
428  double TOL=Rn::getTolerance();
429  this_ostream << "Check generator " << vtxNumber << std::endl;
430  _listOfGenerators[vtxNumber]->dump(std::cout);
431  this_ostream << std::endl;
432  {for (unsigned int i=0; i< _listOfGenerators[vtxNumber]->numberOfFacets(); ++i) {
433  this_ostream << getHalfSpaceNumber( _listOfGenerators[vtxNumber]->getFacet(i) ) << " ";
434  }}
435  this_ostream << std::endl;
436  this_ostream << std::endl;
437  {for (unsigned int i=0; i< _listOfGenerators[vtxNumber]->numberOfFacets(); ++i) {
438  this_ostream << "H" << getHalfSpaceNumber( _listOfGenerators[vtxNumber]->getFacet(i) ) << std::endl;
439  _listOfGenerators[vtxNumber]->getFacet(i)->dump(this_ostream);
440  this_ostream << std::endl;
441  }}
442  this_ostream << std::endl;
443  this_ostream << "Check generator " << vtxNumber << std::endl;
445  {for (iteHS_B.begin(); iteHS_B.end()!=true; iteHS_B.next()) {
446  double halfSpaceNorm = std::inner_product(iteHS_B.current()->begin(), iteHS_B.current()->end(), iteHS_B.current()->begin(), 0.);
447  halfSpaceNorm = sqrt(halfSpaceNorm);
448  double scalarProduct = std::inner_product(_listOfGenerators[vtxNumber]->begin(), _listOfGenerators[vtxNumber]->end(), iteHS_B.current()->begin(), 0.);
449  double distanceToHyperplane = (scalarProduct+iteHS_B.current()->getConstant()) / halfSpaceNorm;
450  this_ostream << "H" << iteHS_B.currentIteratorNumber() << "\t";
451  this_ostream << ": " << distanceToHyperplane;
452  if (distanceToHyperplane<TOL && distanceToHyperplane>-TOL)
453  this_ostream << " (*)";
454  this_ostream << std::endl;
455  }}
456  }
457 
463  const listOfGeometricObjects< boost::shared_ptr<Generator_Rn> >& listGenA,
464  const listOfGeometricObjects< boost::shared_ptr<HalfSpace_Rn> >& listHSB, bool check_all=false) const {
465  std::cout << "Check generators..... ";
466  std::vector< std::vector<int> > listOfFacetsPerGenerator(listGenA.size());
468  {for (iteHS_B.begin(); iteHS_B.end()!=true; iteHS_B.next()) {
469  double halfSpaceNorm =
470  std::inner_product(iteHS_B.current()->begin(), iteHS_B.current()->end(), iteHS_B.current()->begin(), 0.);
471  halfSpaceNorm = sqrt(halfSpaceNorm);
473  {for (iteGN_A_.begin(); iteGN_A_.end()!=true; iteGN_A_.next()) {
474  HalfSpace_Rn::State currentState = checkPoint(iteGN_A_.current(), iteHS_B.current(), halfSpaceNorm);
475  if (currentState == HalfSpace_Rn::hs_ON)
476  listOfFacetsPerGenerator[ iteGN_A_.currentIteratorNumber() ].push_back( iteHS_B.currentIteratorNumber() );
477  else if (currentState == HalfSpace_Rn::hs_OUT)
478  std::cout << "\t### G" << iteGN_A_.currentIteratorNumber() << " is out for half-space "
479  << iteHS_B.currentIteratorNumber() << std::endl;
480  }}
481  }}
482  bool checkGeneratorsOK=true;
484  {for (iteGN_A.begin(); iteGN_A.end()!=true; iteGN_A.next()) {
485  if (listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].empty()==true ||
486  listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].size() < numberOfGeneratorsPerFacet())
487  checkGeneratorsOK = false;
488  if (check_all &&
489  listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].size() != iteGN_A.current()->numberOfFacets())
490  checkGeneratorsOK = false;
491  }}
492  if (checkGeneratorsOK == true)
493  std::cout << "OK" << std::endl;
494  else {
495  std::cout << "KO" << std::endl;
496  {for (iteGN_A.begin(); iteGN_A.end()!=true; iteGN_A.next()) {
497  if (listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].empty()==true ||
498  listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].size() < numberOfGeneratorsPerFacet())
499  std::cout << "\t### G" << iteGN_A.currentIteratorNumber() << " has only "
500  << listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].size() << " facets." << std::endl;
501  if (listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].size() != iteGN_A.current()->numberOfFacets()) {
502  std::cout << "\t### G" << iteGN_A.currentIteratorNumber() << " has different facet size "
503  << listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].size() << " and "
504  << iteGN_A.current()->numberOfFacets() << std::endl;
505  //std::copy(
506  //listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].begin(),
507  //listOfFacetsPerGenerator[ iteGN_A.currentIteratorNumber() ].end(), std::ostream_iterator<unsigned int>(std::cout, " ") );
508  }
509  }}
510  }
511  return checkGeneratorsOK;
512  }
513 
515  void removeGenerator(unsigned int j) {_listOfGenerators.removeGeometricObject(j);}
516 
518  virtual bool checkEdges() const {return true;}
519 
520  void checkFacet(unsigned int fctNumber, std::ostream &this_ostream) const throw (std::out_of_range) {
521  if (fctNumber >= _listOfHalfSpaces.size())
522  throw std::out_of_range("PolyhedralCone_Rn::checkFacet(unsigned int fctNumber, std::ostream &this_ostream) inadequate facet number!");
523  this_ostream.precision(15);
524  this_ostream << "Check facet " << fctNumber << std::endl;
525  _listOfHalfSpaces[fctNumber]->dump(this_ostream);
526  this_ostream << std::endl;
528  double halfSpaceNorm = std::inner_product(
529  _listOfHalfSpaces[fctNumber]->begin(), _listOfHalfSpaces[fctNumber]->end(), _listOfHalfSpaces[fctNumber]->begin(), 0.);
530  halfSpaceNorm = sqrt(halfSpaceNorm);
531  {for (iteGN.begin(); iteGN.end()!=true; iteGN.next()) {
532  HalfSpace_Rn::State currentState = checkPoint(iteGN.current(), _listOfHalfSpaces[fctNumber], halfSpaceNorm);
533  if (currentState == HalfSpace_Rn::hs_ON)
534  this_ostream << iteGN.currentIteratorNumber() << " ";
535  }}
537  //std::vector< boost::shared_ptr<Generator_Rn> > arrayOfGen;
538  //this_ostream << "Maximize" << std::endl << "obj:";
539  //this_ostream << "x_1" << std::endl << std::endl << "Subject To" << std::endl;
540  //{for (unsigned int j=0; j<Rn::getDimension(); ++j) {
541  //this_ostream << "r" << j << ":" << std::endl;
542  //{for (unsigned int i=0; i<arrayOfGen.size(); ++i) {
543  //if (arrayOfGen[i]->getCoordinate(j) > 0.)
544  //this_ostream << " + ";
545  //else
546  //this_ostream << " - ";
547  //this_ostream << fabs(arrayOfGen[i]->getCoordinate(j)) << "x_" << i << " ";
548  //}}
549  //this_ostream << " = " << std::endl;
550  //}}
551  //this_ostream << "r" << Rn::getDimension() << ":" << std::endl;
552  //{for (unsigned int i=0; i<arrayOfGen.size(); ++i) {
553  //this_ostream << " + x_" << i;
554  //}}
555  //this_ostream << " = 1." << std::endl << std::endl;
556  //this_ostream << "Bounds" << std::endl;
557  //{for (unsigned int i=0; i<arrayOfGen.size(); ++i) {
558  //this_ostream << 0. << " <= x_" << i << std::endl;
559  //}}
560  //this_ostream << std::endl;
561  //this_ostream << std::endl << "End" << std::endl;
562  this_ostream << std::endl;
563  double TOL=Rn::getTolerance();
564  {for (iteGN.begin(); iteGN.end()!=true; iteGN.next()) {
565  double scalarProduct = std::inner_product(iteGN.current()->begin(),iteGN.current()->end(), _listOfHalfSpaces[fctNumber]->begin(), 0.);
566  double distanceToHyperplane = (scalarProduct+ _listOfHalfSpaces[fctNumber]->getConstant()) / halfSpaceNorm;
567  this_ostream << "V" << iteGN.currentIteratorNumber() << "\t";
568  this_ostream << ": " << distanceToHyperplane;
569  if (distanceToHyperplane<TOL && distanceToHyperplane>-TOL)
570  this_ostream << " (*)";
571  this_ostream << std::endl;
572  }}
573  }
574 
582  bool checkFacets() const {
583  std::cout << "Check facets......... ";
584  bool checkFacetsOK=true;
585  unsigned int j=0;
586  std::vector<int> listOfGeneratorsPerFacetON(numberOfGenerators());
587  std::vector<int> listOfGeneratorsPerFacetOUT(numberOfGenerators());
589  {for (iteHS.begin(); iteHS.end()!=true; iteHS.next()) {
590  listOfGeneratorsPerFacetON.clear();
591  listOfGeneratorsPerFacetOUT.clear();
593  double halfSpaceNorm = std::inner_product(iteHS.current()->begin(), iteHS.current()->end(), iteHS.current()->begin(), 0.);
594  halfSpaceNorm = sqrt(halfSpaceNorm);
595  {for (iteGN.begin(); iteGN.end()!=true; iteGN.next()) {
596  HalfSpace_Rn::State currentState = checkPoint(iteGN.current(), iteHS.current(), halfSpaceNorm);
597  unsigned int i=iteGN.currentIteratorNumber();
598  if (currentState == HalfSpace_Rn::hs_ON)
599  listOfGeneratorsPerFacetON.push_back(i);
600  else if (currentState == HalfSpace_Rn::hs_OUT)
601  listOfGeneratorsPerFacetOUT.push_back(i);
602  }}
603  if (listOfGeneratorsPerFacetON.empty() == true || listOfGeneratorsPerFacetON.size() < numberOfGeneratorsPerFacet())
604  std::cout<< std::endl << "\t=== Facet " << j << " has only " << listOfGeneratorsPerFacetON.size() << " generators."<< std::endl;
605  if (listOfGeneratorsPerFacetOUT.empty() != true) {
606  {for (unsigned int i=0; i<listOfGeneratorsPerFacetOUT.size(); i++) {
607  checkFacetsOK = false;
608  std::cout<< std::endl;
609  std::cout << "\t### Facet " << j << " excludes generator " << listOfGeneratorsPerFacetOUT[i] << std::endl;
610  }}
611  }
612  j++;
613  }}
614  if (checkFacetsOK == true)
615  std::cout << "OK" << std::endl;
616  return checkFacetsOK;
617  }
618 
621  bool checkEquality(const boost::shared_ptr<PolyhedralCone_Rn>& B, bool getFaceMapping=false) const;
622 
623 
624  // ALGORITHMS
625 
627  void negate() {_listOfHalfSpaces.negate(); _listOfGenerators.negate();}
628 
639  virtual void createTruncatedGenerator(
640  const boost::shared_ptr<Generator_Rn_SD>& y,
641  const boost::shared_ptr<Generator_Rn_SD>& z,
642  boost::shared_ptr<Generator_Rn_SD> newG, double ay, double az, double b=0.) const;
643 
645  boost::shared_ptr<PolyhedralCone_Rn> computeDualPolyhedralCone() const;
646 
648  virtual void computeMinkowskiSum(
649  const boost::shared_ptr<PolyhedralCone_Rn>& A,
650  const boost::shared_ptr<PolyhedralCone_Rn>& B);
651 
653  void dump(std::ostream &this_ostream) const;
654 
656  virtual void createBoundingBox(double) {}
657 
659  virtual void createBoundingSimplex(double) {}
660 
661  protected:
666 };
667 
668 
669 #endif // POLYHEDRALCONE_Rn
unsigned int numberOfHalfSpaces() const
Get the total number of half-spaces.
listOfGeometricObjects< boost::shared_ptr< HalfSpace_Rn > > & getListOfHalfSpaces()
Return the list of half-spaces.
void reset()
Remove all half-spaces and generators.
const listOfGeometricObjects< boost::shared_ptr< Generator_Rn > > & getListOfGenerators() const
Return the list of generators.
virtual unsigned int numberOfGeneratorsPerFacet() const
Each facet in a polyhedral cone has got (n-1) edges.
Creation of a n-coordinate geometric point designed to be shared by its neighbour faces...
Definition: Point_Rn.h:34
void setListOfGenerators(const listOfGeometricObjects< boost::shared_ptr< Generator_Rn > > &gnList)
Set a new list of generators.
const listOfGeometricObjects< boost::shared_ptr< HalfSpace_Rn > > & getListOfHalfSpaces() const
Return the list of half-spaces.
int currentIteratorNumber() const
Return the current position in the list.
Model a polyhedral cone using its two equivalent definitions : the convex hull and the half-space int...
virtual bool checkEdges() const
Always true in the polyhedral cone case.
bool checkGenerators(const listOfGeometricObjects< boost::shared_ptr< Generator_Rn > > &listGenA, const listOfGeometricObjects< boost::shared_ptr< HalfSpace_Rn > > &listHSB, bool check_all=false) const
Check the number of facets per generator and make sure it is compliant with its current constraints...
virtual ~PolyhedralCone_Rn()
Destructor.
virtual void createBoundingBox(double)
At the moment this function is useless in the case of polyhedral cones.
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
const GEOMETRIC_OBJECT current()
Return the current geometric element.
unsigned int getListOfGeneratorsSD(std::vector< boost::shared_ptr< Generator_Rn_SD > > &currentListOfGeneratorsSD)
bool checkNeighbours(const boost::shared_ptr< Generator_Rn > &V1, const boost::shared_ptr< Generator_Rn > &V2, std::vector< boost::shared_ptr< HalfSpace_Rn > > &commonFacets, unsigned int topologicalCode=1) const
void setListOfGeneratorsSD(const std::vector< boost::shared_ptr< Generator_Rn_SD > > &gnList)
Set a new list of generators. The list of half-spaces should have been previously set...
listOfGeometricObjects< boost::shared_ptr< Generator_Rn > > _listOfGenerators
The convex hull of connected points.
PolyhedralCone_Rn(const PolyhedralCone_Rn &A)
Constructor.
void removeHalfSpaces(const std::set< boost::shared_ptr< HalfSpace_Rn > > &setOfRedundantHS)
Remove the half-space number j from its list.
virtual void createBoundingSimplex(double)
At the moment this function is useless in the case of polyhedral cones.
bool checkNeighbours(const boost::shared_ptr< Generator_Rn_SD > &genIn, const boost::shared_ptr< Generator_Rn_SD > &genOut, std::vector< unsigned int > &commonFacets)
Check for polytopes that vertices share (n-1) facets. For polyhedral cones, it must check that vector...
void begin()
Move the iterator at the beginning of the list.
virtual bool isBounded() const
Tell whether this polyhedron is bounded or not, polyhedral cones are not.
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.
void removeGenerator(unsigned int j)
Remove the generator number j from its list.
void checkGenerator(unsigned int vtxNumber, std::ostream &this_ostream) const
Compute all distance from the current point to all half-spaces frontiers.
static polito_EXPORT unsigned int getDimension()
Return the dimension of the cartesian space we work in.
Definition: Rn.cpp:29
#define polito_EXPORT
Definition: polito_Export.h:15
This class is designed to run the list of all geometric objects representing a polytope.
virtual bool checkTopologyAndGeometry() const
As stated by Komei Fukuda "the complexity of the polyhedral verification problem is unknown...
A n-coordinates generator for internal data structure. It can be a vertex or an edge whether it is em...
Definition: Generator_Rn.h:225
void next()
Move the iterator one step forward.
void negate()
Compute the symmetrical polyhedral cone.
This class is designed to contain the list of all generators or half-spaces representing a polytope o...
virtual unsigned int dimension() const
Return the space dimension.
listOfGeometricObjects< boost::shared_ptr< HalfSpace_Rn > > _listOfHalfSpaces
The list of half-spaces defining the polytope.
virtual unsigned int neigbourhoodCondition() const
Two edges are neighbours in a polyhedral cone <=> they share at least (n-2) facets.
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...
void removeHalfSpace(unsigned int j)
Remove the half-space number j from its list.
void checkFacet(unsigned int fctNumber, std::ostream &this_ostream) const
bool checkFacets() const
Detect redundant half spaces and make sure each facet has the right number of generators. Check that the polytope does not have generators violating a constraint defined by a half-space. Check that the polytope does have at least (n-1) generators per half-space frontier. .
void fillNeighbourMatrix(std::vector< std::vector< unsigned int > > &neighboursA, unsigned int topologicalCode=1) const
void push_back(const GEOMETRIC_OBJECT &gn)
Include a new half space in the list.
unsigned int getHalfSpaceNumber(const boost::shared_ptr< HalfSpace_Rn > &F) const
For a given half-space, return its list index.
bool checkNeighbours(const boost::shared_ptr< Generator_Rn > &V1, const boost::shared_ptr< Generator_Rn > &V2, std::vector< HalfSpace_Rn * > &commonFacets, unsigned int topologicalCode=1) const
Check for polytopes that vertices share (n-1) facets. For polyhedral cones, it must check that vector...
PolyhedralCone_Rn()
Constructor.
void addGenerator(boost::shared_ptr< Generator_Rn > vx)
Add the given generator.