politopix  5.0.0
VolumeOfPolytopes_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) 2014-2015 : Delos Vincent
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU 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 General Public License for more details.
13 //
14 // You should have received a copy of the GNU 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 VOLUME_POLYTOPES_Rn
22 #define VOLUME_POLYTOPES_Rn
23 
24 #include <stdexcept>
25 #include <exception>
26 #include <iostream>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <fstream>
30 #include <sstream>
31 #include <set>
32 #include <boost/shared_ptr.hpp>
33 #include <boost/numeric/ublas/io.hpp>
34 #include <boost/numeric/ublas/vector.hpp>
35 #include <boost/numeric/ublas/matrix.hpp>
36 #include "polito_Export.h"
37 #include "Polytope_Rn.h"
38 #include "Rn.h"
39 
40 using namespace boost::numeric::ublas;
41 
43 
44 public:
45  PolytopeToSimplexes(const std::vector< unsigned int >& splitPol, unsigned int dim) {
46  _dimension = dim;
47  //_listOfProcessedVertices.push_back( splitPol[0] );
48  std::vector< unsigned int >::const_iterator itEnd = splitPol.end();
49  std::vector< unsigned int >::const_iterator itBeg = splitPol.begin();
50  //++itBeg;
51  // Insert all elements except the first one.
52  _listOfVerticesToSplit.insert(_listOfVerticesToSplit.begin(), itBeg, itEnd);
53  }
54 
55  PolytopeToSimplexes(const std::vector< unsigned int >& vtx2plit, unsigned int apexNb, unsigned int dim) {
56  _dimension = dim;
57  _listOfProcessedVertices.push_back( apexNb );
58  _listOfVerticesToSplit = vtx2plit;
59  }
60 
61  PolytopeToSimplexes(const std::vector< unsigned int >& vtx2plit, const std::vector< unsigned int >& prcVtx, unsigned int apexNb, unsigned int dim) {
62  _dimension = dim;
63  _listOfProcessedVertices = prcVtx;
64  _listOfProcessedVertices.push_back( apexNb );
65  _listOfVerticesToSplit = vtx2plit;
66  }
67 
68  const std::vector< unsigned int >& getListOfProcessedVertices() const {
69  return _listOfProcessedVertices;
70  }
71 
72  void setListOfProcessedVertices(const std::vector< unsigned int >& LPV) {
73  _listOfProcessedVertices = LPV;
74  }
75 
76  const std::vector< unsigned int >& getListOfVerticesToSplit() const {
77  return _listOfVerticesToSplit;
78  }
79 
80  void setListOfVerticesToSplit(const std::vector< unsigned int >& VTS) {
81  _listOfVerticesToSplit = VTS;
82  }
83 
84  void addProcessedVertex(unsigned int ap) {
85  _listOfProcessedVertices.push_back(ap);
86  }
87 
88  bool checkSimplex() const {
89  if (_dimension+1 == _listOfVerticesToSplit.size())
90  return true;
91  return false;
92  }
93 
94  std::vector< unsigned int > buildPolytope() const {
95  std::vector< unsigned int > pol;
96  std::vector< unsigned int >::const_iterator it;
97  for (it=_listOfProcessedVertices.begin(); it!=_listOfProcessedVertices.end(); ++it)
98  pol.push_back(*it);
99  for (it=_listOfVerticesToSplit.begin(); it!=_listOfVerticesToSplit.end(); ++it)
100  pol.push_back(*it);
101  return pol;
102  }
103 
105  _dimension += _listOfProcessedVertices.size();
106  _listOfProcessedVertices.insert(_listOfProcessedVertices.end(), _listOfVerticesToSplit.begin(), _listOfVerticesToSplit.end());
107  _listOfVerticesToSplit.clear();
108  }
109 
110  unsigned int dimension() const {
111  return _dimension;
112  }
113 
114  void dump(std::ostream &this_ostream, unsigned int shift=0) const {
115  for (unsigned int i=0; i<shift; ++i) this_ostream << "\t";
116  this_ostream << "{" << _dimension << ":";
117  std::copy(getListOfProcessedVertices().begin(), getListOfProcessedVertices().end(), std::ostream_iterator<unsigned int>(this_ostream, " "));
118  this_ostream << std::endl;
119  for (unsigned int i=0; i<shift; ++i) std::cout << "\t";
120  std::copy(getListOfVerticesToSplit().begin(), getListOfVerticesToSplit().end(), std::ostream_iterator<unsigned int>(this_ostream, " "));
121  this_ostream << "}" << std::endl;
122  }
123 
124 
125 protected:
127  std::vector< unsigned int > _listOfProcessedVertices;
129  std::vector< unsigned int > _listOfVerticesToSplit;
131  unsigned int _dimension;
132 };
133 
140 
141  public:
142 
144  VolumeOfPolytopes_Rn(const boost::shared_ptr<Polytope_Rn> P);
145 
147 
150  void splitCloudOfVertices(unsigned int DIM);
151 
153  static double compute(const boost::shared_ptr<Polytope_Rn> P) {
154  VolumeOfPolytopes_Rn volComp(P);
155  unsigned int currentDIM = Rn::getDimension();
156  if (currentDIM == 1) {
157  if (P->numberOfGenerators() == 2) {
158  double a0 = P->getGenerator(0)->getCoordinate(0);
159  double a1 = P->getGenerator(1)->getCoordinate(0);
160  return fabs(a1-a0);
161  }
162  else {
163  std::cerr << "VolumeOfPolytopes_Rn::compute() double description needed." << std::endl;
164  return -1.;
165  }
166  }
167  // Put all other generators in a set (in a logical way as they are numbers)
168  std::vector<unsigned int> attempt2Simplex;
169  std::vector<unsigned int> listOfOthers;
170  for (unsigned int i=1; i<P->numberOfGenerators(); ++i)
171  listOfOthers.push_back(i);
172  try {
173  // Do the hard job.
174  volComp.splitCloudOfVertices(currentDIM);
175 #ifdef DEBUG
176  volComp.dump(std::cout);
177 #endif
178  return volComp.volume();
179  }
180  catch(std::invalid_argument& e) {
181  std::cout << "VolumeOfPolytopes_Rn::compute() : invalid argument exception " << e.what() << std::endl;
182  return -1;
183  }
184  catch(std::out_of_range& e) {
185  std::cout << "VolumeOfPolytopes_Rn::compute() : out of range exception " << e.what() << std::endl;
186  return -1;
187  }
188  catch(std::ios_base::failure& e) {
189  std::cout << "VolumeOfPolytopes_Rn::compute() : in/out exception " << e.what() << std::endl;
190  return -1;
191  }
192  catch(...) {
193  std::cout << "VolumeOfPolytopes_Rn::compute() : unexpected exception caught !" << std::endl;
194  return -1;
195  }
196  }
197 
198  void check() const;
199 
201  double volume();
202 
205  double computeSimplexVolume(const std::set< boost::shared_ptr<Generator_Rn> >& listOfSimplexVertices) const;
206 
209  double determinant(boost::numeric::ublas::matrix<double> a) const;
210 
211  void dump(std::ostream &this_ostream) {
212  std::cout << "List of simplices:" << std::endl;
213  unsigned int counter=0;
214  std::vector< PolytopeToSimplexes >::iterator iteSet;
215  {for (iteSet=_allSimplices.begin(); iteSet!=_allSimplices.end(); ++iteSet) {
216  this_ostream << "Simplex number " << counter << std::endl;
217  std::vector< unsigned int >::const_iterator iteVtx;
218  {for (iteVtx=iteSet->getListOfVerticesToSplit().begin(); iteVtx!=iteSet->getListOfVerticesToSplit().end(); ++iteVtx) {
219  boost::shared_ptr<Generator_Rn> gn = _polytope->getGenerator(*iteVtx);
220  gn->dump( this_ostream );
221  }}
222  this_ostream << std::endl;
223  counter++;
224  }}
225  }
226 
227  void dumpDS(std::ostream &this_ostream) const {
228  std::cout << "Vertices By Facets:" << std::endl;
229  std::vector< std::vector< unsigned int > >::const_iterator iteSet;
230  unsigned int counter=0;
231  {for (iteSet=_verticesByFacets.begin(); iteSet!=_verticesByFacets.end(); ++iteSet) {
232  this_ostream << counter << ": ";
233  std::copy(iteSet->begin(), iteSet->end(), std::ostream_iterator<unsigned int>(std::cout, " "));
234  this_ostream << std::endl;
235  counter++;
236  }}
237  std::cout << "Facets By Vertices:" << std::endl;
238  counter=0;
239  {for (iteSet=_facetsByVertices.begin(); iteSet!=_facetsByVertices.end(); ++iteSet) {
240  this_ostream << counter << ": ";
241  std::copy(iteSet->begin(), iteSet->end(), std::ostream_iterator<unsigned int>(std::cout, " "));
242  this_ostream << std::endl;
243  counter++;
244  }}
245  }
246 
247  void dumpAllSimplices(std::ostream &this_ostream) const {
248  std::vector< PolytopeToSimplexes >::const_iterator itS;
249  {for (itS=_allSimplices.begin(); itS!=_allSimplices.end(); ++itS) {
250  itS->dump(this_ostream);
251  this_ostream << std::endl;
252  }}
253  }
254 
255 
256  protected:
258  std::vector< std::vector< unsigned int > > _verticesByFacets;
260  std::vector< std::vector< unsigned int > > _facetsByVertices;
262  std::vector< PolytopeToSimplexes > _allSimplices;
264  boost::shared_ptr<Polytope_Rn> _polytope;
266  double _volume;
268  unsigned int _dimension;
270  unsigned int _numberOfFacets;
272  unsigned int _numberOfVertices;
273 
274 };
275 
276 #endif // VOLUME_POLYTOPES_Rn
VolumeOfPolytopes_Rn::_facetsByVertices
std::vector< std::vector< unsigned int > > _facetsByVertices
The ordered list of all facets stored by vertices.
Definition: VolumeOfPolytopes_Rn.h:260
PolytopeToSimplexes
Definition: VolumeOfPolytopes_Rn.h:42
PolytopeToSimplexes::PolytopeToSimplexes
PolytopeToSimplexes(const std::vector< unsigned int > &vtx2plit, const std::vector< unsigned int > &prcVtx, unsigned int apexNb, unsigned int dim)
Definition: VolumeOfPolytopes_Rn.h:61
PolytopeToSimplexes::getListOfProcessedVertices
const std::vector< unsigned int > & getListOfProcessedVertices() const
Definition: VolumeOfPolytopes_Rn.h:68
polito_EXPORT
#define polito_EXPORT
Definition: polito_Export.h:15
VolumeOfPolytopes_Rn::dump
void dump(std::ostream &this_ostream)
Definition: VolumeOfPolytopes_Rn.h:211
VolumeOfPolytopes_Rn::dumpDS
void dumpDS(std::ostream &this_ostream) const
Definition: VolumeOfPolytopes_Rn.h:227
PolytopeToSimplexes::PolytopeToSimplexes
PolytopeToSimplexes(const std::vector< unsigned int > &vtx2plit, unsigned int apexNb, unsigned int dim)
Definition: VolumeOfPolytopes_Rn.h:55
VolumeOfPolytopes_Rn::_allSimplices
std::vector< PolytopeToSimplexes > _allSimplices
List to store all the simplices partitioning the polytope.
Definition: VolumeOfPolytopes_Rn.h:262
PolytopeToSimplexes::buildPolytope
std::vector< unsigned int > buildPolytope() const
Definition: VolumeOfPolytopes_Rn.h:94
PolytopeToSimplexes::PolytopeToSimplexes
PolytopeToSimplexes(const std::vector< unsigned int > &splitPol, unsigned int dim)
Definition: VolumeOfPolytopes_Rn.h:45
Rn::getDimension
static polito_EXPORT unsigned int getDimension()
Return the dimension of the cartesian space we work in.
Definition: Rn.cpp:29
VolumeOfPolytopes_Rn
Split a polytope into simplices to compute its volume. Two Algorithms for Determining Volumes of C...
Definition: VolumeOfPolytopes_Rn.h:139
PolytopeToSimplexes::dimension
unsigned int dimension() const
Definition: VolumeOfPolytopes_Rn.h:110
VolumeOfPolytopes_Rn::splitCloudOfVertices
void splitCloudOfVertices(unsigned int DIM)
Definition: VolumeOfPolytopes_Rn.cpp:81
VolumeOfPolytopes_Rn::_volume
double _volume
The volume of the polytope.
Definition: VolumeOfPolytopes_Rn.h:266
PolytopeToSimplexes::setListOfProcessedVertices
void setListOfProcessedVertices(const std::vector< unsigned int > &LPV)
Definition: VolumeOfPolytopes_Rn.h:72
VolumeOfPolytopes_Rn::~VolumeOfPolytopes_Rn
~VolumeOfPolytopes_Rn()
Definition: VolumeOfPolytopes_Rn.h:146
PolytopeToSimplexes::setListOfVerticesToSplit
void setListOfVerticesToSplit(const std::vector< unsigned int > &VTS)
Definition: VolumeOfPolytopes_Rn.h:80
Rn.h
PolytopeToSimplexes::_listOfProcessedVertices
std::vector< unsigned int > _listOfProcessedVertices
The ordered list of vertices as we go down in smaller dimensions spaces.
Definition: VolumeOfPolytopes_Rn.h:127
VolumeOfPolytopes_Rn::_numberOfVertices
unsigned int _numberOfVertices
The number of vertices of the current polytope.
Definition: VolumeOfPolytopes_Rn.h:272
PolytopeToSimplexes::_listOfVerticesToSplit
std::vector< unsigned int > _listOfVerticesToSplit
The ordered list of vertices to be split in lower dimensions.
Definition: VolumeOfPolytopes_Rn.h:129
PolytopeToSimplexes::_dimension
unsigned int _dimension
The current dimension space we work in.
Definition: VolumeOfPolytopes_Rn.h:131
PolytopeToSimplexes::switchToFullDimension
void switchToFullDimension()
Definition: VolumeOfPolytopes_Rn.h:104
PolytopeToSimplexes::dump
void dump(std::ostream &this_ostream, unsigned int shift=0) const
Definition: VolumeOfPolytopes_Rn.h:114
VolumeOfPolytopes_Rn::dumpAllSimplices
void dumpAllSimplices(std::ostream &this_ostream) const
Definition: VolumeOfPolytopes_Rn.h:247
VolumeOfPolytopes_Rn::compute
static double compute(const boost::shared_ptr< Polytope_Rn > P)
Return the volume of the given polytope P.
Definition: VolumeOfPolytopes_Rn.h:153
VolumeOfPolytopes_Rn::_numberOfFacets
unsigned int _numberOfFacets
The number of facets of the current polytope.
Definition: VolumeOfPolytopes_Rn.h:270
VolumeOfPolytopes_Rn::_verticesByFacets
std::vector< std::vector< unsigned int > > _verticesByFacets
The ordered list of all vertices stored by facets.
Definition: VolumeOfPolytopes_Rn.h:258
VolumeOfPolytopes_Rn::_dimension
unsigned int _dimension
As the algorithm goes down in lower dimensions, we want to store the starting space dimension.
Definition: VolumeOfPolytopes_Rn.h:268
VolumeOfPolytopes_Rn::volume
double volume()
Sum the volumes of all simplices partitionning the polytope.
Definition: VolumeOfPolytopes_Rn.cpp:194
PolytopeToSimplexes::getListOfVerticesToSplit
const std::vector< unsigned int > & getListOfVerticesToSplit() const
Definition: VolumeOfPolytopes_Rn.h:76
Polytope_Rn.h
VolumeOfPolytopes_Rn::_polytope
boost::shared_ptr< Polytope_Rn > _polytope
The current polytope we are working on.
Definition: VolumeOfPolytopes_Rn.h:264
PolytopeToSimplexes::checkSimplex
bool checkSimplex() const
Definition: VolumeOfPolytopes_Rn.h:88
polito_Export.h
PolytopeToSimplexes::addProcessedVertex
void addProcessedVertex(unsigned int ap)
Definition: VolumeOfPolytopes_Rn.h:84