26 #include <boost/numeric/ublas/matrix.hpp>
27 #include <boost/numeric/ublas/matrix_proxy.hpp>
28 #include <boost/numeric/ublas/operation.hpp>
29 #include <boost/numeric/ublas/io.hpp>
30 #include <boost/timer.hpp>
54 std::set< ListOfFaces > allPotentialFaces;
55 std::vector< ListOfFaces > thisListOfFacetsPerVertices;
57 {
for (constITER_GN1.begin(); constITER_GN1.end()!=
true; constITER_GN1.next()) {
58 unsigned int NbFacets = constITER_GN1.
current()->numberOfFacets();
60 {
for (
unsigned int j=0; j<NbFacets; j++) {
61 unsigned int NbFj = thisPolytope->getHalfSpaceNumber( constITER_GN1.current()->getFacet(j) );
63 thisListOfFaces.push_back( NbFj );
65 thisListOfFacetsPerVertices.push_back( thisListOfFaces );
66 allPotentialFaces.insert(thisListOfFaces);
70 {
for (
unsigned int dimensionOfFace=1; dimensionOfFace<=RnDIM; ++dimensionOfFace) {
72 std::vector< ListOfFaces > kp1_Faces;
73 std::set< ListOfFaces > kp1_FacesSet;
75 std::vector< ListOfFaces >::iterator it1 = k_Faces.begin(), it2 = k_Faces.begin();
76 for (it1 = k_Faces.begin(); it1 != k_Faces.end(); ) {
78 bool it1StepForward =
false;
79 for (it2 = it1+1; it2 != k_Faces.end(); ) {
80 std::vector< unsigned int > interFace;
81 std::set_intersection(it1->begin(), it1->end(), it2->begin(), it2->end(), std::inserter(interFace, interFace.end()));
91 if (interFace.empty() ==
false) {
92 if (interFace == *it2) {
93 it2 = k_Faces.erase(it2);
98 if (interFace == *it1) {
99 it1 = k_Faces.erase(it1);
101 it1StepForward =
true;
102 if (it1 != k_Faces.end())
107 if (kp1_FacesSet.insert(interFace).second ==
true)
108 kp1_Faces.push_back(interFace);
116 if (it1StepForward ==
false)
125 unsigned int nbHS = thisPolytope->numberOfHalfSpaces();
129 std::vector< std::vector< unsigned int > > allGenPerHS;
130 {
for (
unsigned int j=0; j<nbHS; ++j) {
131 std::vector< unsigned int > genSet;
132 allGenPerHS.push_back(genSet);
135 unsigned int generatorNumber=0;
137 {
for (iteGN.begin(); iteGN.end()!=
true; iteGN.next()) {
138 {
for (
unsigned int ii=0; ii<iteGN.current()->numberOfFacets(); ii++) {
139 unsigned int fctNumber = thisPolytope->getHalfSpaceNumber( iteGN.current()->getFacet(ii) );
140 allGenPerHS[fctNumber].push_back( iteGN.currentIteratorNumber() );
145 unsigned int dim = 0;
146 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
149 std::vector< ListOfFaces >::const_iterator iteFF;
150 for (iteFF=iteF->begin(); iteFF!=iteF->end(); ++iteFF) {
151 ListOfFaces::const_iterator iteFFF;
153 iteFFF=iteFF->
begin();
154 std::vector< unsigned int > INTER = allGenPerHS[*iteFFF];
156 for (; iteFFF!=iteFF->end(); ++iteFFF) {
158 std::vector< unsigned int > partial_INTER;
159 std::set_intersection(INTER.begin(), INTER.end(),
160 allGenPerHS[*iteFFF].begin(), allGenPerHS[*iteFFF].end(),
161 std::inserter(partial_INTER, partial_INTER.end()));
162 INTER = partial_INTER;
174 unsigned int dim = 0, allSizes = 0;
175 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
177 allSizes = allSizes + iteF->size();
180 allSizes = allSizes + 2;
181 this_ostream <<
"FaceEnumeration::printFacesWithFacets, total number of elements = " << allSizes << std::endl;
183 this_ostream <<
"F" << dim <<
": ";
184 std::vector< ListOfFaces >::const_iterator iteFF;
185 for (iteFF=iteF->begin(); iteFF!=iteF->end(); ++iteFF) {
186 ListOfFaces::const_iterator iteFFF;
187 this_ostream <<
" { ";
188 for (iteFFF=iteFF->begin(); iteFFF!=iteFF->end(); ++iteFFF) {
189 this_ostream << *iteFFF <<
" ";
191 this_ostream <<
"} ";
193 this_ostream << std::endl;
199 unsigned int dim = 0, allSizes = 0;
200 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
202 allSizes = allSizes + iteF->size();
205 allSizes = allSizes + 2;
206 this_ostream <<
"FaceEnumeration::printFacesWithVertices, total number of elements = " << allSizes << std::endl;
208 this_ostream <<
"F" << dim <<
": ";
209 std::vector< ListOfFaces >::const_iterator iteFF;
210 for (iteFF=iteF->begin(); iteFF!=iteF->end(); ++iteFF) {
211 ListOfFaces::const_iterator iteFFF;
212 this_ostream <<
" { ";
213 for (iteFFF=iteFF->begin(); iteFFF!=iteFF->end(); ++iteFFF) {
214 this_ostream << *iteFFF <<
" ";
216 this_ostream <<
"} ";
218 this_ostream << std::endl;
224 unsigned int dim = 0, allSizes = 0;
225 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
227 allSizes = allSizes + iteF->size();
230 allSizes = allSizes + 2;
231 this_ostream <<
"FaceEnumeration::printFacesWithVerticesToSage, total number of elements = " << allSizes << std::endl;
233 this_ostream <<
"F" << dim <<
": " << std::endl;
234 std::vector< ListOfFaces >::const_iterator iteFF;
236 std::vector< ListOfFaces >::const_iterator stopFF=iteF->end()-1;
238 for (iteFF=iteF->begin(); iteFF!=stopFF && iteFF!=iteF->end(); ++iteFF) {
239 ListOfFaces::const_iterator iteFFF, stopFFF=iteFF->end()-1;
241 for (iteFFF=iteFF->begin(); iteFFF!=stopFFF; ++iteFFF) {
242 this_ostream << *iteFFF <<
", ";
244 this_ostream << *iteFFF <<
"), ";
248 if (iteFF!=iteF->end()) {
249 ListOfFaces::const_iterator iteFFF, stopFFF=iteFF->end()-1;
251 for (iteFFF=iteFF->begin(); iteFFF!=stopFFF; ++iteFFF) {
252 this_ostream << *iteFFF <<
", ";
254 this_ostream << *iteFFF <<
") ";
257 this_ostream << std::endl;
263 throw (std::ios_base::failure) {
264 std::ifstream file(filename.c_str(), std::ifstream::in);
266 std::string s(
"Unable to open ");
269 throw std::ios_base::failure(s);
276 std::ofstream file(filename.c_str());
278 std::string s(
"Unable to open ");
281 throw std::ios_base::failure(s);
288 throw (std::out_of_range){
291 std::getline(this_stream, line);
293 std::getline(this_stream, line);
294 std::istringstream iline(line);
295 unsigned int spaceDimension, totalNumberOfFaces;
296 iline >> spaceDimension;
297 iline >> totalNumberOfFaces;
298 latt.resize(spaceDimension+1);
299 unsigned nbReadFaces = 0;
300 while (nbReadFaces != totalNumberOfFaces) {
302 std::getline(this_stream, line);
303 std::istringstream iline3(line);
304 unsigned int dimensionOfFace, numberOfVtx, val;
305 iline3 >> dimensionOfFace;
306 iline3 >> numberOfVtx;
307 if (dimensionOfFace > spaceDimension) {
308 std::string errorMsg(
"FaceEnumeration::load() wrong face dimension");
309 throw std::out_of_range(errorMsg);
312 for (
unsigned int count=0; count<numberOfVtx; ++count) {
314 thisOne.push_back(val);
316 latt[dimensionOfFace].push_back(thisOne);
322 unsigned int allSizes = 0;
323 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
324 for (iteF=latt.begin(); iteF!=latt.end(); ++iteF) {
325 allSizes = allSizes + iteF->size();
331 unsigned int totalNumberOfFaces = allSizes;
332 this_stream <<
"# Dimension LatticeSize" << std::endl;
333 this_stream << spaceDimension <<
" ";
334 this_stream << totalNumberOfFaces << std::endl;
335 unsigned dimReadFaces = 0;
336 for (iteF=latt.begin(); iteF!=latt.end(); ++iteF) {
337 std::vector< ListOfFaces >::const_iterator iteFF;
338 for (iteFF=iteF->begin(); iteFF!=iteF->end(); ++iteFF) {
339 this_stream << dimReadFaces <<
" " << iteFF->size() <<
" ";
340 ListOfFaces::const_iterator iteFFF;
341 for (iteFFF=iteFF->begin(); iteFFF!=iteFF->end(); ++iteFFF)
342 this_stream << *iteFFF <<
" ";
343 this_stream << std::endl;
351 boost::shared_ptr<Polytope_Rn> currentSum = *(arrayOfPolytopes.begin());
352 boost::shared_ptr<Polytope_Rn> A = currentSum;
353 std::vector< boost::shared_ptr<Generator_Rn> > listOfGenerators_A, listOfGenerators_B, listOfGenerators_C;
354 std::vector< boost::shared_ptr<PolyhedralCone_Rn> > listOfDualCones_A, listOfDualCones_B, listOfDualCones_C;
356 {
for (
unsigned int i=0; i<A->numberOfGenerators(); ++i) {
357 listOfGenerators_A.push_back(A->getGenerator(i));
358 const boost::shared_ptr<PolyhedralCone_Rn>& cone_a = A->getPrimalCone( A->getGenerator(i) );
359 listOfDualCones_A.push_back( cone_a->computeDualPolyhedralCone() );
362 std::vector< boost::shared_ptr<Polytope_Rn> >::const_iterator itePol;
363 for (itePol = arrayOfPolytopes.begin()+1; itePol != arrayOfPolytopes.end(); ++itePol) {
364 boost::shared_ptr<Polytope_Rn> B = *itePol;
365 {
for (
unsigned int i=0; i<B->numberOfGenerators(); ++i) {
366 listOfGenerators_B.push_back(B->getGenerator(i));
367 const boost::shared_ptr<PolyhedralCone_Rn>& cone_b = B->getPrimalCone( B->getGenerator(i) );
368 listOfDualCones_B.push_back( cone_b->computeDualPolyhedralCone() );
370 _A2C.resize(listOfGenerators_A.size());
371 _B2C.resize(listOfGenerators_B.size());
374 computeCommonRefinement(listOfGenerators_A, listOfGenerators_B, listOfGenerators_C, listOfDualCones_A, listOfDualCones_B, listOfDualCones_C);
375 listOfDualCones_A.clear();
376 listOfDualCones_A.swap(listOfDualCones_C);
377 listOfGenerators_A.clear();
378 listOfGenerators_A.swap(listOfGenerators_C);
379 listOfGenerators_C.clear();
380 listOfGenerators_B.clear();
381 listOfDualCones_C.clear();
382 listOfDualCones_B.clear();
399 const std::vector< boost::shared_ptr<Generator_Rn> >& listOfGenerators_A,
400 const std::vector< boost::shared_ptr<Generator_Rn> >& listOfGenerators_B,
401 std::vector< boost::shared_ptr<Generator_Rn> >& listOfGenerators_C,
402 const std::vector< boost::shared_ptr<PolyhedralCone_Rn> >& listOfDualCones_A,
403 const std::vector< boost::shared_ptr<PolyhedralCone_Rn> >& listOfDualCones_B,
404 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >& listOfDualCones_C) throw (std::domain_error) {
405 if (listOfGenerators_A.size()==0 || listOfGenerators_B.size()==0)
406 throw std::domain_error(
"MinkowskiSum::computeCommonRefinement() cannot work without vertices.");
408 std::vector< boost::shared_ptr<Generator_Rn> >::const_iterator LVX_A, LVX_B;
409 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >::const_iterator LPC_A, LPC_B;
410 unsigned int minkowskiVertexNumber=0;
411 {
for (LPC_B=listOfDualCones_B.begin(), LVX_B=listOfGenerators_B.begin(); LPC_B!=listOfDualCones_B.end(); ++LPC_B, ++LVX_B) {
412 boost::shared_ptr<PolyhedralCone_Rn> Cb = *(LPC_B);
413 {
for (LPC_A=listOfDualCones_A.begin(), LVX_A=listOfGenerators_A.begin(); LPC_A!=listOfDualCones_A.end(); ++LPC_A, ++LVX_A) {
414 unsigned int a_i = LPC_A-listOfDualCones_A.begin();
415 unsigned int b_j = LPC_B-listOfDualCones_B.begin();
416 boost::shared_ptr<PolyhedralCone_Rn> Ca = *(LPC_A);
436 boost::shared_ptr<PolyhedralCone_Rn> intersectionCone;
459 int truncationStep = Ca->numberOfHalfSpaces();
461 for (iteHSA.begin(); iteHSA.end()!=
true; iteHSA.next())
462 intersectionCone->addHalfSpace(iteHSA.current());
464 for (iteGNA.begin(); iteGNA.end()!=
true; iteGNA.next()) {
466 boost::shared_ptr<Generator_Rn> gn(
new Generator_Rn( *(iteGNA.current()) ));
467 intersectionCone->addGenerator(gn);
470 for (iteHSB.begin(); iteHSB.end()!=
true; iteHSB.next())
471 intersectionCone->addHalfSpace(iteHSB.current());
476 lexmin_ite(intersectionCone->getListOfHalfSpaces());
480 boost::shared_ptr<PolyhedralCone_Rn>,
484 DD(intersectionCone, lexmin_ite, NRP, truncationStep);
485 bool notEmpty = !DD.getIsEmpty();
487 std::cout <<
"@@@ nbEDG=" << intersectionCone->numberOfGenerators() <<
"( ";
490 if (notEmpty ==
true && intersectionCone->numberOfGenerators() >= RnDIM) {
491 listOfDualCones_C.push_back(intersectionCone);
492 boost::shared_ptr<Generator_Rn> VX(
new Generator_Rn(RnDIM));
493 VX->makeSum(*LVX_A, *LVX_B);
495 for (
unsigned int k=0; k<RnDIM; k++) {
496 std::cout << (*LVX_A)->getCoordinate(k) <<
"+" << (*LVX_B)->getCoordinate(k)
497 <<
"=" << VX->getCoordinate(k) <<
"\t";
513 listOfGenerators_C.push_back(VX);
518 _A2C[a_i].push_back(minkowskiVertexNumber);
519 _B2C[b_j].push_back(minkowskiVertexNumber);
520 ++minkowskiVertexNumber;
523 std::cout <<
")" << std::endl;
532 throw std::domain_error(
"MinkowskiSum::compute() needs two double-description polytopes i.e. with both vertices and half-spaces.");
561 std::vector< boost::shared_ptr<Generator_Rn> > listOfGenerators_A;
562 std::vector< boost::shared_ptr<Generator_Rn> > listOfGenerators_B;
563 std::vector< boost::shared_ptr<PolyhedralCone_Rn> > listOfDualCones_A;
564 std::vector< boost::shared_ptr<PolyhedralCone_Rn> > listOfDualCones_B;
565 {
for (
unsigned int i=0; i<
_firstOperand->numberOfGenerators(); ++i) {
566 listOfGenerators_A.push_back(
_firstOperand->getGenerator(i));
568 listOfDualCones_A.push_back( cone_a->computeDualPolyhedralCone() );
570 {
for (
unsigned int i=0; i<
_secondOperand->numberOfGenerators(); ++i) {
573 listOfDualCones_B.push_back( cone_b->computeDualPolyhedralCone() );
589 boost::numeric::ublas::matrix<double> matOfVtx(
_NF_Vertices.size(), RnDIM);
591 unsigned int vtxNumber=0;
592 std::vector< boost::shared_ptr<Generator_Rn> >::iterator iteVX2;
594 boost::numeric::ublas::matrix_row< boost::numeric::ublas::matrix<double> > matRow(matOfVtx, vtxNumber);
595 std::copy( (*iteVX2)->begin(), (*iteVX2)->end(), matRow.begin());
599 std::vector< std::vector< unsigned int > > VerticesPerFacet;
601 std::vector< boost::shared_ptr<HalfSpace_Rn> > setOfAllHalfSpaces;
602 std::vector< boost::shared_ptr<Generator_Rn> >::iterator iteVX =
_NF_Vertices.begin();
603 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >::iterator itePC =
_NF_Cones.begin();
604 {
for (; itePC!=
_NF_Cones.end(); ++itePC, ++iteVX) {
606 {
for (
unsigned int u=0; u<(*itePC)->numberOfGenerators(); ++u) {
608 boost::shared_ptr<HalfSpace_Rn> HS;
612 for (
unsigned int coord_count=0; coord_count<RnDIM; coord_count++) {
613 double this_coord = (*itePC)->getGenerator(u)->getCoordinate(coord_count);
615 HS->setCoefficient(coord_count, this_coord);
616 sum = sum + this_coord*(*iteVX)->getCoordinate(coord_count);
618 HS->setConstant(-sum);
620 std::vector< unsigned int > vtxStates;
621 double halfSpaceNorm = std::inner_product(HS->begin(), HS->end(), HS->begin(), 0.);
622 halfSpaceNorm = sqrt(halfSpaceNorm);
624 boost::numeric::ublas::vector<double> dist2Hyp = prod(matOfVtx, HS->vect());
628 boost::numeric::ublas::scalar_vector<double> scalsum(
_NF_Vertices.size(),sum);
629 dist2Hyp = dist2Hyp - scalsum;
630 dist2Hyp = dist2Hyp / halfSpaceNorm;;
631 {
for (
unsigned int vtxNumber2=0; vtxNumber2<dist2Hyp.size(); ++vtxNumber2) {
632 if (dist2Hyp(vtxNumber2) > TOL) {
646 vtxStates.push_back(vtxNumber2);
652 {
for (
unsigned int i=0; i<VerticesPerFacet.size() && inserted==
false; ++i) {
653 if (VerticesPerFacet[i].size() == vtxStates.size()) {
654 if (VerticesPerFacet[i] == vtxStates)
657 else if (VerticesPerFacet[i].size() > vtxStates.size()) {
658 if (std::includes(VerticesPerFacet[i].begin(), VerticesPerFacet[i].end(), vtxStates.begin(), vtxStates.end()) ==
true) {
666 if (std::includes(vtxStates.begin(), vtxStates.end(), VerticesPerFacet[i].begin(), VerticesPerFacet[i].end()) ==
true) {
667 VerticesPerFacet[i] = vtxStates;
668 setOfAllHalfSpaces[i] = HS;
674 if (inserted ==
false) {
675 VerticesPerFacet.push_back(vtxStates);
676 setOfAllHalfSpaces.push_back(HS);
684 unsigned int vtxNb=0;
691 bool foundEnoughHS=
false;
693 {
for (
unsigned int i=0; i<VerticesPerFacet.size() && foundEnoughHS==
false; ++i) {
694 {
for (
unsigned int j=0; j<VerticesPerFacet[i].size(); ++j) {
695 if (VerticesPerFacet[i][j] == vtxNb)
698 foundEnoughHS =
true;
701 if (foundEnoughHS ==
true) {
702 _sum->addGenerator( (*iteVX) );
713 {
for (
unsigned int i=0; i<VerticesPerFacet.size(); ++i) {
714 {
for (
unsigned int j=0; j<VerticesPerFacet[i].size(); ++j) {
716 _NF_Vertices[ VerticesPerFacet[i][j] ]->setFacet( setOfAllHalfSpaces[i] );
718 _sum->addHalfSpace( setOfAllHalfSpaces[i],
false);
735 unsigned int currentNumber=0;
736 std::vector< boost::shared_ptr<HalfSpace_Rn> > setOfAllHalfSpaces;
737 std::vector< boost::shared_ptr<Generator_Rn> >::iterator iteVX =
_NF_Vertices.begin();
738 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >::iterator itePC =
_NF_Cones.begin();
740 std::map< boost::shared_ptr<Generator_Rn>,
double > allEdgesNorms;
741 {
for (; itePC!=
_NF_Cones.end(); ++itePC, ++iteVX) {
750 std::vector< unsigned int > c_kMinkowskiVertices;
751 std::vector< unsigned int >::const_iterator iteNgb;
753 {
for (
unsigned int j=0; j<
_neighboursA[a_i].size(); ++j) {
755 {
for (
unsigned int k=0; k<
_A2C[a_i_ngb].size(); ++k) {
757 if (
_A2C[a_i_ngb][k] != currentNumber)
758 c_kMinkowskiVertices.push_back(
_A2C[a_i_ngb][k] );
761 {
for (
unsigned int i=0; i<
_neighboursB[b_j].size(); ++i) {
763 {
for (
unsigned int k=0; k<
_B2C[b_j_ngb].size(); ++k) {
764 if (
_B2C[b_j_ngb][k] != currentNumber)
765 c_kMinkowskiVertices.push_back(
_B2C[b_j_ngb][k] );
771 {
for (
unsigned int u=0; u<(*itePC)->numberOfGenerators(); ++u) {
773 boost::shared_ptr<HalfSpace_Rn> HS;
777 for (
unsigned int coord_count=0; coord_count<RnDIM; coord_count++) {
778 double this_coord = (*itePC)->getGenerator(u)->getCoordinate(coord_count);
780 HS->setCoefficient(coord_count, this_coord);
781 sum = sum + this_coord*(*iteVX)->getCoordinate(coord_count);
783 HS->setConstant(-sum);
784 const boost::shared_ptr<Generator_Rn>& gn1=(*itePC)->getGenerator(u);
785 double gn1_sum2 = std::inner_product(gn1->begin(), gn1->end(), gn1->begin(), 0.);
786 {
for (iteNgb=c_kMinkowskiVertices.begin(); iteNgb!=c_kMinkowskiVertices.end(); ++iteNgb) {
789 {
for (
unsigned int v=0; v<
_NF_Cones[*iteNgb]->numberOfGenerators() && check==
true; ++v) {
790 const boost::shared_ptr<Generator_Rn>& gn2=
_NF_Cones[*iteNgb]->getGenerator(v);
791 double scal_prod = std::inner_product(gn1->begin(), gn1->end(), gn2->begin(), 0.);
792 if (scal_prod > 0.) {
793 double coef1 = scal_prod / gn1_sum2;
795 if (gn1->getNormalDistance(gn2, coef1, RnDIM) < TOL2) {
801 else if (scal_prod > 0.) {
802 double gn2_sum2 = 0.;
804 std::map< boost::shared_ptr<Generator_Rn>,
double >::iterator iteNorm = allEdgesNorms.find( gn2 );
805 if (iteNorm == allEdgesNorms.end())
806 gn2_sum2 = std::inner_product(gn2->begin(), gn2->end(), gn2->begin(), 0.);
808 gn2_sum2 = iteNorm->second;
809 double coef2 = scal_prod / gn2_sum2;
810 if (gn2->getNormalDistance(gn1, coef2, RnDIM) < TOL2) {
814 if (iteNorm != allEdgesNorms.end())
815 allEdgesNorms.erase(iteNorm);
823 (*iteVX)->setFacet(HS);
824 setOfAllHalfSpaces.push_back( HS );
826 (*itePC)->removeGenerator(u);
830 _sum->addGenerator( (*iteVX) );
836 if ((*itePC)->numberOfGenerators() != 0)
837 throw std::domain_error(
"MinkowskiSum::processNormalFan1() dual cones reduction not operational !");
841 std::vector< boost::shared_ptr<HalfSpace_Rn> >::const_iterator iteHS=setOfAllHalfSpaces.begin();
842 {
for (iteHS=setOfAllHalfSpaces.begin(); iteHS!=setOfAllHalfSpaces.end(); ++iteHS) {
844 _sum->addHalfSpace( *iteHS,
false);
853 std::vector< boost::shared_ptr<Generator_Rn> >::iterator iteVX=
_NF_Vertices.begin();
854 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >::iterator itePC=
_NF_Cones.begin();
855 for (; itePC!=
_NF_Cones.end(); ++itePC, ++iteVX) {
861 for (
unsigned int u=0; u<(*itePC)->numberOfGenerators(); u++) {
862 boost::shared_ptr<HalfSpace_Rn> HS;
866 for (
unsigned int coord_count=0; coord_count<RnDIM; coord_count++) {
867 double this_coord = (*itePC)->getGenerator(u)->getCoordinate(coord_count);
869 HS->setCoefficient(coord_count, this_coord);
870 sum = sum + this_coord*(*iteVX)->getCoordinate(coord_count);
872 HS->setConstant(-sum);
875 (*iteVX)->setFacet(
_sum->addHalfSpace(HS,
true));
878 _sum->addGenerator( (*iteVX) );
887 const std::set< unsigned int >& firstOperandCaps,
888 const std::set< unsigned int >& secondOperandCaps,
889 std::set< unsigned int >& sumCaps)
throw (std::domain_error)
892 std::cout <<
"PseudoSumWithoutCaps::computeCapHalfSpaces()" << endl;
894 if (_sum->numberOfGenerators()==0)
895 throw std::domain_error(
"PseudoSumWithoutCaps::computeCapHalfSpaces() We need to compute the Minkowski sum first.");
898 unsigned int facetNumber=0;
899 std::vector< std::vector<unsigned int> > listOfVerticesPerFacet(_sum->numberOfHalfSpaces());
901 {
for (iteHS.begin(); iteHS.end()!=
true; iteHS.next()) {
903 std::cout <<
"facetNumber=" << facetNumber <<
":";
906 {
for (iteGN.begin(); iteGN.end()!=
true; iteGN.next()) {
907 for (
unsigned int i=0; i<iteGN.current()->numberOfFacets(); ++i) {
908 if (iteGN.current()->getFacet(i) == iteHS.current()) {
909 listOfVerticesPerFacet[facetNumber].push_back(iteGN.currentIteratorNumber());
923 std::vector< std::pair< unsigned int, unsigned int > > thisMinkDecomposition;
924 std::vector< boost::shared_ptr<PolyhedralCone_Rn> > theseNF_Cones;
925 std::vector< boost::shared_ptr<Generator_Rn> > theseNF_Vertices;
926 {
for (
unsigned int i=0; i<_MinkowskiDecompositionOK.size(); ++i) {
927 if (_MinkowskiDecompositionOK[i] ==
true) {
928 thisMinkDecomposition.push_back( _MinkowskiDecomposition[i] );
929 theseNF_Vertices.push_back( _NF_Vertices[i] );
930 theseNF_Cones.push_back( _NF_Cones[i] );
933 _MinkowskiDecomposition = thisMinkDecomposition;
934 _NF_Vertices = theseNF_Vertices;
935 _NF_Cones = theseNF_Cones;
938 unsigned int sumFacetNb = 0;
939 std::vector< std::vector<unsigned int> >::const_iterator itVtx = listOfVerticesPerFacet.begin();
940 {
for (; itVtx!=listOfVerticesPerFacet.end(); ++itVtx) {
941 std::set< unsigned int > listOfVtxA, listOfVtxB;
942 std::vector<unsigned int>::const_iterator MinkVtx = itVtx->begin();
944 std::cout << endl <<
"Compute F_A and F_B for facet " << sumFacetNb << endl;
946 {
for (; MinkVtx!=itVtx->end(); ++MinkVtx) {
947 unsigned int MinkNumber = *MinkVtx;
948 listOfVtxA.insert( _MinkowskiDecomposition[MinkNumber].first );
949 listOfVtxB.insert( _MinkowskiDecomposition[MinkNumber].second);
952 std::set<unsigned int> listOfFacetsOfVtxA;
953 std::set<unsigned int> tmpInterResForA, tmp2InterResForA;
954 std::set<unsigned int>::const_iterator itVtxNbOperand;
955 itVtxNbOperand = listOfVtxA.begin();
956 for (
unsigned int ngb_count=0; ngb_count<_firstOperand->getGenerator(*itVtxNbOperand)->numberOfFacets(); ngb_count++) {
957 boost::shared_ptr<HalfSpace_Rn> Fi = _firstOperand->getGenerator(*itVtxNbOperand)->getFacet(ngb_count);
958 listOfFacetsOfVtxA.insert(_firstOperand->getHalfSpaceNumber(Fi));
963 std::cout <<
" V = {";
964 std::cout <<
" " << *itVtxNbOperand;
966 tmpInterResForA = listOfFacetsOfVtxA;
968 {
for (; itVtxNbOperand!=listOfVtxA.end(); ++itVtxNbOperand) {
970 std::cout <<
" " << *itVtxNbOperand;
972 std::set<unsigned int> curListOfFacetsOfVtxA;
973 for (
unsigned int ngb_count=0; ngb_count<_firstOperand->getGenerator(*itVtxNbOperand)->numberOfFacets(); ngb_count++) {
974 boost::shared_ptr<HalfSpace_Rn> Fi = _firstOperand->getGenerator(*itVtxNbOperand)->getFacet(ngb_count);
975 curListOfFacetsOfVtxA.insert(_firstOperand->getHalfSpaceNumber(Fi));
977 tmp2InterResForA = tmpInterResForA;
978 tmpInterResForA.clear();
979 std::set_intersection(
980 tmp2InterResForA.begin(),
981 tmp2InterResForA.end(),
982 curListOfFacetsOfVtxA.begin(),
983 curListOfFacetsOfVtxA.end(),
984 std::inserter(tmpInterResForA, tmpInterResForA.end()));
985 if (listOfFacetsOfVtxA.empty() ==
true)
986 throw std::domain_error(
"PseudoSumWithoutCaps::computeCapHalfSpaces() the i-Face of polytope A has 0 half-space.");
992 std::set<unsigned int> InterResForA;
993 std::set_intersection(
994 tmpInterResForA.begin(),
995 tmpInterResForA.end(),
996 firstOperandCaps.begin(),
997 firstOperandCaps.end(),
998 std::inserter(InterResForA, InterResForA.end()));
1000 std::cout <<
" ; H = { ";
1001 std::copy(InterResForA.begin(), InterResForA.end(), std::ostream_iterator<unsigned int>(std::cout,
" ") );
1007 if (InterResForA.empty() !=
true)
1008 sumCaps.insert( sumFacetNb );
1014 std::set<unsigned int> listOfFacetsOfVtxB;
1015 std::set<unsigned int> tmpInterResForB, tmp2InterResForB;
1016 itVtxNbOperand = listOfVtxB.begin();
1017 for (
unsigned int ngb_count=0; ngb_count<_secondOperand->getGenerator(*itVtxNbOperand)->numberOfFacets(); ngb_count++) {
1018 boost::shared_ptr<HalfSpace_Rn> Fi = _secondOperand->getGenerator(*itVtxNbOperand)->getFacet(ngb_count);
1019 listOfFacetsOfVtxB.insert(_secondOperand->getHalfSpaceNumber(Fi));
1022 std::cout <<
"F_B:";
1023 std::cout <<
" V = {";
1024 std::cout <<
" " << *itVtxNbOperand;
1026 tmpInterResForB = listOfFacetsOfVtxB;
1028 {
for (; itVtxNbOperand!=listOfVtxB.end(); ++itVtxNbOperand) {
1030 std::cout <<
" " << *itVtxNbOperand;
1032 std::set<unsigned int> curListOfFacetsOfVtxB;
1033 for (
unsigned int ngb_count=0; ngb_count<_secondOperand->getGenerator(*itVtxNbOperand)->numberOfFacets(); ngb_count++) {
1034 boost::shared_ptr<HalfSpace_Rn> Fi = _secondOperand->getGenerator(*itVtxNbOperand)->getFacet(ngb_count);
1035 curListOfFacetsOfVtxB.insert(_secondOperand->getHalfSpaceNumber(Fi));
1037 tmp2InterResForB = tmpInterResForB;
1038 tmpInterResForB.clear();
1039 std::set_intersection(
1040 tmp2InterResForB.begin(),
1041 tmp2InterResForB.end(),
1042 curListOfFacetsOfVtxB.begin(),
1043 curListOfFacetsOfVtxB.end(),
1044 std::inserter(tmpInterResForB, tmpInterResForB.end()));
1045 if (listOfFacetsOfVtxB.empty() ==
true)
1046 throw std::domain_error(
"PseudoSumWithoutCaps::computeCapHalfSpaces() the j-Face of polytope B has 0 half-space.");
1052 std::set<unsigned int> InterResForB;
1053 std::set_intersection(
1054 tmpInterResForB.begin(),
1055 tmpInterResForB.end(),
1056 secondOperandCaps.begin(),
1057 secondOperandCaps.end(),
1058 std::inserter(InterResForB, InterResForB.end()));
1060 std::cout <<
" ; H = { ";
1061 std::copy(InterResForB.begin(), InterResForB.end(), std::ostream_iterator<unsigned int>(std::cout,
" ") );
1068 if (InterResForB.empty() !=
true)
1069 sumCaps.insert( sumFacetNb );
1079 const std::set<unsigned int>& firstOperandCaps,
1080 const std::set<unsigned int>& secondOperandCaps,
1081 std::set<unsigned int>& newCaps,
1084 if (
_sum->numberOfHalfSpaces() == 0 ||
_sum->numberOfGeneratorsPerFacet() == 0)
1085 throw std::domain_error(
"PseudoSumWithoutCaps::rebuildSum() _sum is not computed.");
1087 std::set< unsigned int > sumCaps;
1090 std::cout <<
"firstOperandCaps=" << firstOperandCaps.size() << std::endl;
1091 std::cout <<
"secondOperandCaps=" << secondOperandCaps.size() << std::endl;
1092 std::cout <<
"sumCaps=" << sumCaps.size() << std::endl;
1096 boost::shared_ptr<Polytope_Rn> newSum;
1098 newSum->createBoundingBox(bb_size);
1099 std::vector< boost::shared_ptr<HalfSpace_Rn> > tryCapsForNewSum;
1102 for (iteHS1.begin(); iteHS1.end()!=
true; iteHS1.next()) {
1103 tryCapsForNewSum.push_back(iteHS1.current());
1107 for (iteHS2.begin(); iteHS2.end()!=
true; iteHS2.next()) {
1108 if (sumCaps.find(iteHS2.currentIteratorNumber()) == sumCaps.end())
1109 newSum->addHalfSpace(iteHS2.current());
1118 boost::shared_ptr<PolyhedralCone_Rn>,
1121 DD(newSum, lexmin_ite, NRP, truncationStep);
1124 constIteratorOfListOfGeometricObjects< boost::shared_ptr<HalfSpace_Rn> > iteHS3(newSum->getListOfHalfSpaces());
1125 for (iteHS3.begin(); iteHS3.end()!=
true; iteHS3.next()) {
1126 std::vector< boost::shared_ptr<HalfSpace_Rn> >::const_iterator iteCaps = tryCapsForNewSum.begin();
1127 for (; iteCaps!=tryCapsForNewSum.end(); ++iteCaps) {
1128 if (iteHS3.current() == *iteCaps) {
1129 newCaps.insert(iteHS3.currentIteratorNumber());
1142 const boost::shared_ptr<Polytope_Rn>& A,
1143 const boost::shared_ptr<Polytope_Rn>& B,
1144 boost::shared_ptr<Polytope_Rn>& C,
1145 const std::set< unsigned int >& firstOperandCaps,
1146 const std::set< unsigned int >& secondOperandCaps,
1147 std::set< unsigned int >& newCaps,
1152 C->createBoundingBox(bb_size);
1153 std::vector< boost::shared_ptr<HalfSpace_Rn> > RnCaps;
1156 for (iteHS0.begin(); iteHS0.end()!=
true; iteHS0.next()) {
1157 RnCaps.push_back(iteHS0.current());
1161 for (iteHS1.begin(); iteHS1.end()!=
true; iteHS1.next()) {
1162 if (firstOperandCaps.find(iteHS1.currentIteratorNumber()) == firstOperandCaps.end())
1163 C->addHalfSpace(iteHS1.current());
1167 for (iteHS2.begin(); iteHS2.end()!=
true; iteHS2.next()) {
1168 if (secondOperandCaps.find(iteHS2.currentIteratorNumber()) == secondOperandCaps.end())
1169 C->addHalfSpace(iteHS2.current());
1178 boost::shared_ptr<PolyhedralCone_Rn>,
1181 DD(C, lexmin_ite, NRP, truncationStep);
1185 constIteratorOfListOfGeometricObjects< boost::shared_ptr<HalfSpace_Rn> > iteHS3(C->getListOfHalfSpaces());
1186 for (iteHS3.begin(); iteHS3.end()!=
true; iteHS3.next()) {
1187 std::vector< boost::shared_ptr<HalfSpace_Rn> >::const_iterator iteCaps = RnCaps.begin();
1188 for (; iteCaps!=RnCaps.end(); ++iteCaps) {
1189 if (iteHS3.current() == *iteCaps) {
1190 newCaps.insert(iteHS3.currentIteratorNumber());
1200 if (pol->numberOfGenerators() != 0) {
1202 {
for (iteGN.begin(); iteGN.end()!=
true; iteGN.next()) {
1203 const boost::shared_ptr<Generator_Rn>& v2_A = iteGN.
current();
1204 boost::numeric::ublas::vector<double> coord = v2_A->vect() + v2t;
1205 v2_A->setCoordinates(coord);
1208 if (pol->numberOfHalfSpaces() != 0) {
1210 {
for (iteHS.begin(); iteHS.end()!=
true; iteHS.next()) {
1211 const boost::shared_ptr<HalfSpace_Rn>& hs = iteHS.
current();
1212 double prod = std::inner_product(hs->begin(), hs->end(), v2t.begin(), 0.);
1213 hs->setConstant( hs->getConstant()-prod );
1220 if (pol->numberOfGenerators() != 0) {
1221 for (
unsigned int i=0; i<gravity_center.size (); ++i)
1222 gravity_center(i) = 0.;
1224 {
for (iteGN.begin(); iteGN.end()!=
true; iteGN.next()) {
1225 gravity_center += iteGN.
current()->vect();
1227 gravity_center /= pol->numberOfGenerators();
1230 throw std::domain_error(
"DoubleDescriptionFromGenerators::Compute() the polytope already does not have generators.");
1237 throw std::domain_error(
"TopGeomTools::scalingFactor() scaling factor too small.");
1238 if (pol->numberOfGenerators() != 0) {
1240 {
for (iteGN.begin(); iteGN.end()!=
true; iteGN.next()) {
1241 for (
unsigned int i=0; i<dim; ++i)
1242 iteGN.
current()->setCoordinate(i, iteGN.current()->getCoordinate(i)*factor);
1245 if (pol->numberOfHalfSpaces() != 0) {
1247 for (iteHS.begin(); iteHS.end()!=
true; iteHS.next())
1248 iteHS.
current()->setConstant( iteHS.current()->getConstant()*factor);
1255 const boost::shared_ptr<Polytope_Rn>& original_pol,
1256 boost::shared_ptr<Polytope_Rn>& polar_pol,
1257 bool forceComputation,
double bb_size)
throw (invalid_argument) {
1259 unsigned int dim = original_pol->dimension();
1261 if (original_pol->numberOfGenerators() != 0) {
1263 {
for (iteGN.begin(); iteGN.end()!=
true; iteGN.next()) {
1264 boost::shared_ptr<HalfSpace_Rn> HS;
1266 HS->setConstant(1.);
1267 boost::numeric::ublas::vector< double >::const_iterator iteCoord = iteGN.
current()->begin();
1268 unsigned int coord_count = 0;
1269 {
for ( ; iteCoord != iteGN.current()->end(); ++iteCoord ) {
1271 HS->setCoefficient(coord_count, *iteCoord);
1275 polar_pol->addHalfSpace(HS);
1277 if (forceComputation ==
true) {
1279 polar_pol->createBoundingBox(bb_size);
1283 unsigned int truncationStep = 2*dim;
1285 boost::shared_ptr<PolyhedralCone_Rn>,
1288 DD(polar_pol, lexmin_ite, NRP, truncationStep);
1290 catch(invalid_argument& except) {
1291 cerr <<
"Invalid argument exception in TopGeomTools::PolarPolytope() " << except.what() << endl;
1294 catch(out_of_range& except) {
1295 cerr <<
"Out of range exception in TopGeomTools::PolarPolytope() " << except.what() << endl;
1298 catch(ios_base::failure& except) {
1299 cerr <<
"In/out exception in TopGeomTools::PolarPolytope() " << except.what() << endl;
1302 catch(logic_error& except) {
1303 cerr <<
"Logic error exception in TopGeomTools::PolarPolytope() " << except.what() << endl;
1307 cerr <<
"Unexpected exception caught in TopGeomTools::PolarPolytope() !" << endl;
1315 if (original_pol->numberOfHalfSpaces() != 0) {
1317 {
for (iteHS.begin(); iteHS.end()!=
true; iteHS.next()) {
1318 if (iteHS.current()->getConstant() < TOL)
1319 throw std::invalid_argument(
"TopGeomTools::PolarPolytope() the input polytope should contain the origin.");
1320 boost::numeric::ublas::vector<double> copyOfHSCoef(iteHS.current()->vect());
1322 copyOfHSCoef = copyOfHSCoef / iteHS.
current()->getConstant();
1323 boost::shared_ptr<Generator_Rn> GN;
1325 GN->setCoordinates(copyOfHSCoef);
1337 polar_pol->addGenerator(GN);
1345 const std::set< unsigned int >& listOfHyperplanes,
1346 const boost::shared_ptr<Polytope_Rn>& original_pol,
1347 boost::shared_ptr<Polytope_Rn>& proj_pol)
throw (invalid_argument)
1351 if (listOfHyperplanes.empty()==
true || listOfHyperplanes.size()>
Rn::getDimension())
1352 throw std::invalid_argument(
"TopGeomTools::projectPolytopeOnCanonicalHyperplanes() wrong list of hyperplanes to project");
1353 unsigned int projectedDimension = listOfHyperplanes.size();
1358 std::vector< boost::shared_ptr<Generator_Rn> > newArrayOfGN;
1360 {
for (iteGN.begin(); iteGN.end()!=
true; iteGN.next()) {
1362 boost::shared_ptr<Generator_Rn> VX;
1364 for (
unsigned int i=1; i<=currentDimension; ++i) {
1365 if (listOfHyperplanes.find(i) != listOfHyperplanes.end()) {
1367 VX->setCoordinate(j, iteGN.current()->getCoordinate(i-1));
1371 bool foundEqual =
false;
1372 std::vector< boost::shared_ptr<Generator_Rn> >::const_iterator iteNew = newArrayOfGN.
begin();
1373 for ( ; iteNew != newArrayOfGN.end() && foundEqual ==
false; ++iteNew) {
1377 if (foundEqual ==
false)
1378 newArrayOfGN.push_back( VX );
1381 std::vector< boost::shared_ptr<Generator_Rn> >::const_iterator iteNew2 = newArrayOfGN.begin();
1382 for ( ; iteNew2 != newArrayOfGN.end(); ++iteNew2)
1383 proj_pol->addGenerator(*iteNew2);
1389 proj_pol->checkTopologyAndGeometry();
1396 const std::set< unsigned int >& originalSpaceDirections,
1397 unsigned int totalSpaceDimension,
1398 const boost::shared_ptr<Polytope_Rn>& original_polytope,
1399 boost::shared_ptr<PolyhedralCone_Rn>& extruded_polyhedron)
throw (invalid_argument) {
1402 if (originalSpaceDirections.empty()==
true || originalSpaceDirections.size()>
Rn::getDimension())
1403 throw std::invalid_argument(
"TopGeomTools::extrudeInCanonicalDirections() wrong definition of the original space");
1410 {
for (iteHS.begin(); iteHS.end()!=
true; iteHS.next()) {
1411 boost::shared_ptr<HalfSpace_Rn> newHS;
1413 newHS->setConstant(iteHS.current()->getConstant());
1414 unsigned int shift = 0;
1415 for (
unsigned int i=1; i<=totalSpaceDimension; ++i) {
1417 if (originalSpaceDirections.find(i) != originalSpaceDirections.end()) {
1418 newHS->setCoefficient(i-1, iteHS.current()->getCoefficient(i-shift-1));
1421 newHS->setCoefficient(i-1, 0.);
1425 extruded_polyhedron->addHalfSpace(newHS);
1437 throw (invalid_argument, out_of_range, ios_base::failure, logic_error) {
1438 unsigned int dim = pol->dimension();
1440 if (pol->numberOfHalfSpaces() != 0)
1441 throw std::domain_error(
"DoubleDescriptionFromGenerators::Compute() the polytope already has half-spaces.");
1442 if (pol->numberOfGenerators() == 0)
1443 throw std::domain_error(
"DoubleDescriptionFromGenerators::Compute() the polytope does not have generators.");
1452 boost::numeric::ublas::vector<double> gravity_center(dim);
1459 boost::shared_ptr<Polytope_Rn> polar_pol(
new Polytope_Rn());
1479 void Visualization::gnuplot2D(
const boost::shared_ptr<Polytope_Rn>& polygon,
const std::string& name,
double col, std::ostream& out)
throw (std::domain_error) {
1481 throw std::domain_error(
"Visualization::gnuplot(std::ostream& out) dimension is not 2 ");
1482 out <<
"set object " << name <<
" polygon from ";
1483 boost::shared_ptr<HalfSpace_Rn> oldHS;
1484 boost::shared_ptr<Generator_Rn> startVTX,referenceVTX;
1487 std::set< boost::shared_ptr<Generator_Rn> > alreadyProcessedVTX;
1488 {
for (LVX_A.begin(); LVX_A.end()!=
true; LVX_A.next()) {
1489 if (alreadyProcessedVTX.find(LVX_A.current()) == alreadyProcessedVTX.end()) {
1490 referenceVTX = LVX_A.current();
1491 alreadyProcessedVTX.insert(referenceVTX);
1492 boost::shared_ptr<HalfSpace_Rn> referenceHS = referenceVTX->getFacet(0);
1493 if (referenceHS == oldHS)
1494 referenceHS = referenceVTX->getFacet(1);
1496 out << LVX_A.current()->getCoordinate(0) <<
"," << LVX_A.current()->getCoordinate(1) <<
" to ";
1498 {
for (LVX_B.begin(); LVX_B.end()!=
true; LVX_B.next()) {
1499 if (alreadyProcessedVTX.find(LVX_B.current()) == alreadyProcessedVTX.end()) {
1500 if (referenceHS == LVX_B.current()->getFacet(0)) {
1501 referenceHS = referenceVTX->getFacet(1);
1503 out << LVX_B.
current()->getCoordinate(0) <<
"," << LVX_B.current()->getCoordinate(1) <<
" to ";
1504 referenceVTX = LVX_B.current();
1505 alreadyProcessedVTX.insert(referenceVTX);
1507 else if (referenceHS == LVX_B.current()->getFacet(1)) {
1508 referenceHS = referenceVTX->getFacet(0);
1510 out << LVX_B.current()->getCoordinate(0) <<
"," << LVX_B.current()->getCoordinate(1) <<
" to ";
1511 referenceVTX = LVX_B.current();
1512 alreadyProcessedVTX.insert(referenceVTX);
1518 out << startVTX->getCoordinate(0) <<
"," << startVTX->getCoordinate(1);
1519 out <<
" lc palette " << col << std::endl;
std::vector< bool > _MinkowskiDecompositionOK
Tell whether _MinkowskiDecomposition had to be considered or not.
void printFacesWithVerticesToSage(std::ostream &this_ostream) const
static polito_EXPORT void setDimension(unsigned int dim)
Set the dimension for the cartesian space we work in.
std::vector< std::vector< unsigned int > > _neighboursB
Store the neighbours of each vertex of B.
void printFacesWithVertices(std::ostream &this_ostream) const
MinkowskiSum()
Sets up the data structure for the computation of the Minkowski sum of two polytopes.
Model a polytope using its two equivalent definitions : the convex hull and the half-space intersecti...
std::vector< std::vector< ListOfFaces > > _allFacesWithFacets
int currentIteratorNumber() const
Return the current position in the list.
void processNormalFan1()
Do the final job after having intersected all dual cones. The reduction process uses neighbourhood pr...
A half-space whose frontier is a linear (n-1) dimension space. _constant + _coefficients[0].x1 + ... + _coefficients[n-1].xn >= 0.
Model a polyhedral cone using its two equivalent definitions : the convex hull and the half-space int...
Compute the Minkowski sum of two polytopes.
std::vector< std::vector< ListOfFaces > > _allFacesWithVertices
void printFacesWithFacets(std::ostream &this_ostream) const
static void gnuplot2D(const boost::shared_ptr< Polytope_Rn > &polygon, const std::string &name, double col, std::ostream &out)
Provide the drwing of polygon under the gnuplot format.
const GEOMETRIC_OBJECT current()
Return the current geometric element.
boost::shared_ptr< Polytope_Rn > rebuildSum(const std::set< unsigned int > &firstOperandCaps, const std::set< unsigned int > &secondOperandCaps, std::set< unsigned int > &newCaps, double bb_size=1000.)
Remove the cap half-spaces stored in sets and then truncate again.
boost::shared_ptr< Polytope_Rn > _sum
std::vector< std::vector< unsigned int > > _A2C
Store the polyhedrical cap in C of each vertex of A.
std::vector< unsigned int > ListOfFaces
const boost::shared_ptr< Polytope_Rn > _firstOperand
void begin()
Move the iterator at the beginning of the list.
void processNormalFan2()
Do the final job after having intersected all dual cones. The reduction process builds half-spaces an...
std::vector< std::vector< unsigned int > > _neighboursA
Store the neighbours of each vertex of A.
static void ComputeWithFacets(const boost::shared_ptr< Polytope_Rn > &A, FaceEnumeration &FaceEnum)
static polito_EXPORT double getTolerance()
Give the minimum distance between two points.
const boost::shared_ptr< Polytope_Rn > _secondOperand
Combinatorial face enumeration for polytopes.
std::vector< std::vector< unsigned int > > _B2C
Store the polyhedrical cap in C of each vertex of B.
static void save(const std::string &filename, const std::vector< std::vector< ListOfFaces > > &latt)
Save the polytope lattice.
static polito_EXPORT unsigned int getDimension()
Return the dimension of the cartesian space we work in.
This class can be more time-consuming than WeakRedundancyProcessing or NoRedundancyProcessing because...
A n-coordinates generator, which can be a vertex or an edge whether it is contained by a polytope or ...
static void ComputeWithVertices(const boost::shared_ptr< Polytope_Rn > &A, FaceEnumeration &FaceEnum)
This class is designed to run the list of all geometric objects representing a polytope.
std::vector< boost::shared_ptr< PolyhedralCone_Rn > > _NF_Cones
The normal fan polyhedrical cones list.
void computeCommonRefinement(const std::vector< boost::shared_ptr< Generator_Rn > > &listOfGenerators_A, const std::vector< boost::shared_ptr< Generator_Rn > > &listOfGenerators_B, std::vector< boost::shared_ptr< Generator_Rn > > &listOfGenerators_C, const std::vector< boost::shared_ptr< PolyhedralCone_Rn > > &listOfDualCones_A, const std::vector< boost::shared_ptr< PolyhedralCone_Rn > > &listOfDualCones_B, std::vector< boost::shared_ptr< PolyhedralCone_Rn > > &listOfDualCones_C)
Just compute the common refinement of the two operands normal fans.
std::vector< std::pair< unsigned int, unsigned int > > _MinkowskiDecomposition
Store the genitors in A and B of each vertex of C.
static void Compute(const boost::shared_ptr< Polytope_Rn > &A)
void computeCapHalfSpaces(const std::set< unsigned int > &firstOperandCaps, const std::set< unsigned int > &secondOperandCaps, std::set< unsigned int > &sumCaps)
Return the cap half-spaces of the sum in function of the two operands cap half-spaces.
PseudoIntersectionWithoutCaps(const boost::shared_ptr< Polytope_Rn > &A, const boost::shared_ptr< Polytope_Rn > &B, boost::shared_ptr< Polytope_Rn > &C, const std::set< unsigned int > &firstOperandCaps, const std::set< unsigned int > &secondOperandCaps, std::set< unsigned int > &newCaps, double bb_size=1000.)
Remove all cap half-spaces and then compute the intersection of two capped polytopes.
static int Compute(boost::shared_ptr< Polytope_Rn > &pol, double bb_size=1000.)
Use the polarity to get the facets from the generators.
boost::shared_ptr< Polytope_Rn > compute()
Compute the common refinement of the two operands normal fans and then build the sum.
void processNormalFan0()
Do the final job after having intersected all dual cones. The reduction process simply compares all d...
The algorithm implemented here is an incremental algorithm as mentioned in How Good are Convex Hull ...
static void load(const std::string &filename, std::vector< std::vector< ListOfFaces > > &latt)
Load the polytope lattice.
std::vector< boost::shared_ptr< Generator_Rn > > _NF_Vertices
The list of C vertices.