politopix  4.1.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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 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 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  // Put all other generators in a set (in a logical way as they are numbers)
157  std::vector< unsigned int > attempt2Simplex;
158  std::vector< unsigned int > listOfOthers;
159  for (unsigned int i=1; i<P->numberOfGenerators(); ++i)
160  listOfOthers.push_back(i);
161  try {
162  // Do the hard job.
163  volComp.splitCloudOfVertices(currentDIM);
164 #ifdef DEBUG
165  volComp.dump(std::cout);
166 #endif
167  return volComp.volume();
168  }
169  catch(std::invalid_argument& e) {
170  std::cout << "VolumeOfPolytopes_Rn::compute() : invalid argument exception " << e.what() << std::endl;
171  return -1;
172  }
173  catch(std::out_of_range& e) {
174  std::cout << "VolumeOfPolytopes_Rn::compute() : out of range exception " << e.what() << std::endl;
175  return -1;
176  }
177  catch(std::ios_base::failure& e) {
178  std::cout << "VolumeOfPolytopes_Rn::compute() : in/out exception " << e.what() << std::endl;
179  return -1;
180  }
181  catch(...) {
182  std::cout << "VolumeOfPolytopes_Rn::compute() : unexpected exception caught !" << std::endl;
183  return -1;
184  }
185  }
186 
187  void check() const throw (std::domain_error);
188 
190  double volume();
191 
194  double computeSimplexVolume(const std::set< boost::shared_ptr<Generator_Rn> >& listOfSimplexVertices) const;
195 
198  double determinant(boost::numeric::ublas::matrix<double> a) const;
199 
200  void dump(std::ostream &this_ostream) {
201  std::cout << "List of simplices:" << std::endl;
202  unsigned int counter=0;
203  std::vector< PolytopeToSimplexes >::iterator iteSet;
204  {for (iteSet=_allSimplices.begin(); iteSet!=_allSimplices.end(); ++iteSet) {
205  this_ostream << "Simplex number " << counter << std::endl;
206  std::vector< unsigned int >::const_iterator iteVtx;
207  {for (iteVtx=iteSet->getListOfVerticesToSplit().begin(); iteVtx!=iteSet->getListOfVerticesToSplit().end(); ++iteVtx) {
208  boost::shared_ptr<Generator_Rn> gn = _polytope->getGenerator(*iteVtx);
209  gn->dump( this_ostream );
210  }}
211  this_ostream << std::endl;
212  counter++;
213  }}
214  }
215 
216  void dumpDS(std::ostream &this_ostream) const {
217  std::cout << "Vertices By Facets:" << std::endl;
218  std::vector< std::vector< unsigned int > >::const_iterator iteSet;
219  unsigned int counter=0;
220  {for (iteSet=_verticesByFacets.begin(); iteSet!=_verticesByFacets.end(); ++iteSet) {
221  this_ostream << counter << ": ";
222  std::copy(iteSet->begin(), iteSet->end(), std::ostream_iterator<unsigned int>(std::cout, " "));
223  this_ostream << std::endl;
224  counter++;
225  }}
226  std::cout << "Facets By Vertices:" << std::endl;
227  counter=0;
228  {for (iteSet=_facetsByVertices.begin(); iteSet!=_facetsByVertices.end(); ++iteSet) {
229  this_ostream << counter << ": ";
230  std::copy(iteSet->begin(), iteSet->end(), std::ostream_iterator<unsigned int>(std::cout, " "));
231  this_ostream << std::endl;
232  counter++;
233  }}
234  }
235 
236  void dumpAllSimplices(std::ostream &this_ostream) const {
237  std::vector< PolytopeToSimplexes >::const_iterator itS;
238  {for (itS=_allSimplices.begin(); itS!=_allSimplices.end(); ++itS) {
239  itS->dump(this_ostream);
240  this_ostream << std::endl;
241  }}
242  }
243 
244 
245  protected:
247  std::vector< std::vector< unsigned int > > _verticesByFacets;
249  std::vector< std::vector< unsigned int > > _facetsByVertices;
251  std::vector< PolytopeToSimplexes > _allSimplices;
253  boost::shared_ptr<Polytope_Rn> _polytope;
255  double _volume;
257  unsigned int _dimension;
259  unsigned int _numberOfFacets;
261  unsigned int _numberOfVertices;
262 
263 };
264 
265 #endif // VOLUME_POLYTOPES_Rn
unsigned int dimension() const
std::vector< unsigned int > buildPolytope() const
std::vector< unsigned int > _listOfProcessedVertices
The ordered list of vertices as we go down in smaller dimensions spaces.
std::vector< PolytopeToSimplexes > _allSimplices
List to store all the simplices partitioning the polytope.
void dump(std::ostream &this_ostream, unsigned int shift=0) const
unsigned int _numberOfFacets
The number of facets of the current polytope.
std::vector< unsigned int > _listOfVerticesToSplit
The ordered list of vertices to be split in lower dimensions.
std::vector< std::vector< unsigned int > > _verticesByFacets
The ordered list of all vertices stored by facets.
unsigned int _dimension
The current dimension space we work in.
const std::vector< unsigned int > & getListOfVerticesToSplit() const
void dumpDS(std::ostream &this_ostream) const
boost::shared_ptr< Polytope_Rn > _polytope
The current polytope we are working on.
Split a polytope into simplices to compute its volume. Two Algorithms for Determining Volumes of C...
void addProcessedVertex(unsigned int ap)
unsigned int _numberOfVertices
The number of vertices of the current polytope.
static polito_EXPORT unsigned int getDimension()
Return the dimension of the cartesian space we work in.
Definition: Rn.cpp:29
double _volume
The volume of the polytope.
static double compute(const boost::shared_ptr< Polytope_Rn > P)
Return the volume of the given polytope P.
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
std::vector< std::vector< unsigned int > > _facetsByVertices
The ordered list of all facets stored by vertices.
const std::vector< unsigned int > & getListOfProcessedVertices() const
double volume()
Sum the volumes of all simplices partitionning the polytope.
unsigned int _dimension
As the algorithm goes down in lower dimensions, we want to store the starting space dimension...
#define polito_EXPORT
Definition: polito_Export.h:15
void splitCloudOfVertices(unsigned int DIM)
PolytopeToSimplexes(const std::vector< unsigned int > &vtx2plit, const std::vector< unsigned int > &prcVtx, unsigned int apexNb, unsigned int dim)
PolytopeToSimplexes(const std::vector< unsigned int > &vtx2plit, unsigned int apexNb, unsigned int dim)
void dump(std::ostream &this_ostream)
PolytopeToSimplexes(const std::vector< unsigned int > &splitPol, unsigned int dim)
void setListOfProcessedVertices(const std::vector< unsigned int > &LPV)
void setListOfVerticesToSplit(const std::vector< unsigned int > &VTS)
void dumpAllSimplices(std::ostream &this_ostream) const