26 #include <boost/numeric/ublas/io.hpp>
27 #include <boost/numeric/ublas/lu.hpp>
28 #include <boost/numeric/ublas/vector.hpp>
29 #include <boost/numeric/ublas/matrix.hpp>
30 #include <boost/numeric/ublas/symmetric.hpp>
31 #include <boost/numeric/ublas/operation.hpp>
32 #include <boost/numeric/ublas/matrix_proxy.hpp>
33 #include <boost/timer.hpp>
57 std::set< ListOfFaces > allPotentialFaces;
58 std::vector< ListOfFaces > thisListOfFacetsPerVertices;
60 {
for (constITER_GN1.
begin(); constITER_GN1.
end()!=
true; constITER_GN1.
next()) {
61 unsigned int NbFacets = constITER_GN1.
current()->numberOfFacets();
63 {
for (
unsigned int j=0; j<NbFacets; j++) {
64 unsigned int NbFj = thisPolytope->getHalfSpaceNumber( constITER_GN1.
current()->getFacet(j) );
66 thisListOfFaces.push_back( NbFj );
68 thisListOfFacetsPerVertices.push_back( thisListOfFaces );
69 allPotentialFaces.insert(thisListOfFaces);
73 {
for (
unsigned int dimensionOfFace=1; dimensionOfFace<=RnDIM; ++dimensionOfFace) {
75 std::vector< ListOfFaces > kp1_Faces;
76 std::set< ListOfFaces > kp1_FacesSet;
78 std::vector< ListOfFaces >::iterator it1 = k_Faces.begin(), it2 = k_Faces.begin();
79 for (it1 = k_Faces.begin(); it1 != k_Faces.end(); ) {
81 bool it1StepForward =
false;
82 for (it2 = it1+1; it2 != k_Faces.end(); ) {
83 std::vector< unsigned int > interFace;
84 std::set_intersection(it1->begin(), it1->end(), it2->begin(), it2->end(), std::inserter(interFace, interFace.end()));
94 if (interFace.empty() ==
false) {
95 if (interFace == *it2) {
96 it2 = k_Faces.erase(it2);
101 if (interFace == *it1) {
102 it1 = k_Faces.erase(it1);
104 it1StepForward =
true;
105 if (it1 != k_Faces.end())
110 if (kp1_FacesSet.insert(interFace).second ==
true)
111 kp1_Faces.push_back(interFace);
119 if (it1StepForward ==
false)
128 unsigned int nbHS = thisPolytope->numberOfHalfSpaces();
132 std::vector< std::vector< unsigned int > > allGenPerHS;
133 {
for (
unsigned int j=0; j<nbHS; ++j) {
134 std::vector< unsigned int > genSet;
135 allGenPerHS.push_back(genSet);
138 unsigned int generatorNumber=0;
141 {
for (
unsigned int ii=0; ii<iteGN.
current()->numberOfFacets(); ii++) {
142 unsigned int fctNumber = thisPolytope->getHalfSpaceNumber( iteGN.
current()->getFacet(ii) );
148 unsigned int dim = 0;
149 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
152 std::vector< ListOfFaces >::const_iterator iteFF;
153 for (iteFF=iteF->begin(); iteFF!=iteF->end(); ++iteFF) {
154 ListOfFaces::const_iterator iteFFF;
156 iteFFF=iteFF->begin();
157 std::vector< unsigned int > INTER = allGenPerHS[*iteFFF];
159 for (; iteFFF!=iteFF->end(); ++iteFFF) {
161 std::vector< unsigned int > partial_INTER;
162 std::set_intersection(INTER.begin(), INTER.end(),
163 allGenPerHS[*iteFFF].begin(), allGenPerHS[*iteFFF].end(),
164 std::inserter(partial_INTER, partial_INTER.end()));
165 INTER = partial_INTER;
177 unsigned int dim = 0, allSizes = 0;
178 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
180 allSizes = allSizes + iteF->size();
183 allSizes = allSizes + 2;
184 this_ostream <<
"FaceEnumeration::printFacesWithFacets, total number of elements = " << allSizes << std::endl;
186 this_ostream <<
"F" << dim <<
": ";
187 std::vector< ListOfFaces >::const_iterator iteFF;
188 for (iteFF=iteF->begin(); iteFF!=iteF->end(); ++iteFF) {
189 ListOfFaces::const_iterator iteFFF;
190 this_ostream <<
" { ";
191 for (iteFFF=iteFF->begin(); iteFFF!=iteFF->end(); ++iteFFF) {
192 this_ostream << *iteFFF <<
" ";
194 this_ostream <<
"} ";
196 this_ostream << std::endl;
202 unsigned int dim = 0, allSizes = 0;
203 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
205 allSizes = allSizes + iteF->size();
208 allSizes = allSizes + 2;
209 this_ostream <<
"FaceEnumeration::printFacesWithVertices, total number of elements = " << allSizes << std::endl;
211 this_ostream <<
"F" << dim <<
": ";
212 std::vector< ListOfFaces >::const_iterator iteFF;
213 for (iteFF=iteF->begin(); iteFF!=iteF->end(); ++iteFF) {
214 ListOfFaces::const_iterator iteFFF;
215 this_ostream <<
" { ";
216 for (iteFFF=iteFF->begin(); iteFFF!=iteFF->end(); ++iteFFF) {
217 this_ostream << *iteFFF <<
" ";
219 this_ostream <<
"} ";
221 this_ostream << std::endl;
227 unsigned int dim = 0, allSizes = 0;
228 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
230 allSizes = allSizes + iteF->size();
233 allSizes = allSizes + 2;
234 this_ostream <<
"FaceEnumeration::printFacesWithVerticesToSage, total number of elements = " << allSizes << std::endl;
236 this_ostream <<
"F" << dim <<
": " << std::endl;
237 std::vector< ListOfFaces >::const_iterator iteFF;
238 std::vector< ListOfFaces >::const_iterator stopFF=iteF->end()-1;
239 for (iteFF=iteF->begin(); iteFF!=stopFF && iteFF!=iteF->end(); ++iteFF) {
240 ListOfFaces::const_iterator iteFFF, stopFFF=iteFF->end()-1;
242 for (iteFFF=iteFF->begin(); iteFFF!=stopFFF; ++iteFFF) {
243 this_ostream << *iteFFF <<
", ";
245 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 <<
") ";
256 this_ostream << std::endl;
262 std::ifstream file(filename.c_str(), std::ifstream::in);
264 std::string s(
"Unable to open ");
267 throw std::ios_base::failure(s);
274 std::ofstream file(filename.c_str());
276 std::string s(
"Unable to open ");
279 throw std::ios_base::failure(s);
288 std::getline(this_stream, line);
290 std::getline(this_stream, line);
291 std::istringstream iline(line);
292 unsigned int spaceDimension, totalNumberOfFaces;
293 iline >> spaceDimension;
294 iline >> totalNumberOfFaces;
295 latt.resize(spaceDimension+1);
296 unsigned nbReadFaces = 0;
297 while (nbReadFaces != totalNumberOfFaces) {
299 std::getline(this_stream, line);
300 std::istringstream iline3(line);
301 unsigned int dimensionOfFace, numberOfVtx, val;
302 iline3 >> dimensionOfFace;
303 iline3 >> numberOfVtx;
304 if (dimensionOfFace > spaceDimension) {
305 std::string errorMsg(
"FaceEnumeration::load() wrong face dimension");
306 throw std::out_of_range(errorMsg);
309 for (
unsigned int count=0; count<numberOfVtx; ++count) {
311 thisOne.push_back(val);
313 latt[dimensionOfFace].push_back(thisOne);
319 unsigned int allSizes = 0;
320 std::vector< std::vector< ListOfFaces > >::const_iterator iteF;
321 for (iteF=latt.begin(); iteF!=latt.end(); ++iteF) {
322 allSizes = allSizes + iteF->size();
328 unsigned int totalNumberOfFaces = allSizes;
329 this_stream <<
"# Dimension LatticeSize" << std::endl;
330 this_stream << spaceDimension <<
" ";
331 this_stream << totalNumberOfFaces << std::endl;
332 unsigned dimReadFaces = 0;
333 for (iteF=latt.begin(); iteF!=latt.end(); ++iteF) {
334 std::vector< ListOfFaces >::const_iterator iteFF;
335 for (iteFF=iteF->begin(); iteFF!=iteF->end(); ++iteFF) {
336 this_stream << dimReadFaces <<
" " << iteFF->size() <<
" ";
337 ListOfFaces::const_iterator iteFFF;
338 for (iteFFF=iteFF->begin(); iteFFF!=iteFF->end(); ++iteFFF)
339 this_stream << *iteFFF <<
" ";
340 this_stream << std::endl;
348 boost::shared_ptr<Polytope_Rn> currentSum = *(arrayOfPolytopes.begin());
349 boost::shared_ptr<Polytope_Rn> A = currentSum;
350 std::vector< boost::shared_ptr<Generator_Rn> > listOfGenerators_A, listOfGenerators_B, listOfGenerators_C;
351 std::vector< boost::shared_ptr<PolyhedralCone_Rn> > listOfDualCones_A, listOfDualCones_B, listOfDualCones_C;
353 std::vector< std::vector<unsigned int> > neighboursA(A->numberOfGenerators());
354 A->fillIrredundantNeighbourMatrix(neighboursA);
355 {
for (
unsigned int i=0; i<A->numberOfGenerators(); ++i) {
356 listOfGenerators_A.push_back(A->getGenerator(i));
357 const boost::shared_ptr<PolyhedralCone_Rn>& cone_a = A->getPrimalCone(i, neighboursA[i]);
358 listOfDualCones_A.push_back( cone_a->computeDualPolyhedralCone() );
361 std::vector< boost::shared_ptr<Polytope_Rn> >::const_iterator itePol;
362 for (itePol = arrayOfPolytopes.begin()+1; itePol != arrayOfPolytopes.end(); ++itePol) {
363 boost::shared_ptr<Polytope_Rn> B = *itePol;
364 std::vector< std::vector<unsigned int> > neighboursB(B->numberOfGenerators());
365 B->fillIrredundantNeighbourMatrix(neighboursB);
366 {
for (
unsigned int i=0; i<B->numberOfGenerators(); ++i) {
367 listOfGenerators_B.push_back(B->getGenerator(i));
368 const boost::shared_ptr<PolyhedralCone_Rn>& cone_b = B->getPrimalCone(i, neighboursB[i]);
369 listOfDualCones_B.push_back( cone_b->computeDualPolyhedralCone() );
371 _A2C.resize(listOfGenerators_A.size());
372 _B2C.resize(listOfGenerators_B.size());
375 computeCommonRefinement(listOfGenerators_A, listOfGenerators_B, listOfGenerators_C, listOfDualCones_A, listOfDualCones_B, listOfDualCones_C);
376 listOfDualCones_A.clear();
377 listOfDualCones_A.swap(listOfDualCones_C);
378 listOfGenerators_A.clear();
379 listOfGenerators_A.swap(listOfGenerators_C);
380 listOfGenerators_C.clear();
381 listOfGenerators_B.clear();
382 listOfDualCones_C.clear();
383 listOfDualCones_B.clear();
400 const std::vector< boost::shared_ptr<Generator_Rn> >& listOfGenerators_A,
401 const std::vector< boost::shared_ptr<Generator_Rn> >& listOfGenerators_B,
402 std::vector< boost::shared_ptr<Generator_Rn> >& listOfGenerators_C,
403 const std::vector< boost::shared_ptr<PolyhedralCone_Rn> >& listOfDualCones_A,
404 const std::vector< boost::shared_ptr<PolyhedralCone_Rn> >& listOfDualCones_B,
405 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >& listOfDualCones_C) {
406 if (listOfGenerators_A.size()==0 || listOfGenerators_B.size()==0)
407 throw std::domain_error(
"MinkowskiSum::computeCommonRefinement() cannot work without vertices.");
409 std::vector< boost::shared_ptr<Generator_Rn> >::const_iterator LVX_A, LVX_B;
410 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >::const_iterator LPC_A, LPC_B;
411 unsigned int minkowskiVertexNumber=0;
412 {
for (LPC_B=listOfDualCones_B.begin(), LVX_B=listOfGenerators_B.begin(); LPC_B!=listOfDualCones_B.end(); ++LPC_B, ++LVX_B) {
413 boost::shared_ptr<PolyhedralCone_Rn> Cb = *(LPC_B);
414 {
for (LPC_A=listOfDualCones_A.begin(), LVX_A=listOfGenerators_A.begin(); LPC_A!=listOfDualCones_A.end(); ++LPC_A, ++LVX_A) {
415 unsigned int a_i = LPC_A-listOfDualCones_A.begin();
416 unsigned int b_j = LPC_B-listOfDualCones_B.begin();
417 boost::shared_ptr<PolyhedralCone_Rn> Ca = *(LPC_A);
437 boost::shared_ptr<PolyhedralCone_Rn> intersectionCone;
440 std::cout <<
"=== Cone from A number " << a_i << std::endl;
441 std::cout <<
"=== Cone from B number " << b_j << std::endl;
442 std::ostringstream stream_A;
443 stream_A <<
"EX/ConeA";
446 std::string coneAfile = stream_A.str();
448 Ca->checkTopologyAndGeometry();
449 std::ostringstream stream_B;
450 stream_B <<
"EX/ConeB";
453 std::string coneBfile = stream_B.str();
455 Cb->checkTopologyAndGeometry();
458 int truncationStep = Ca->numberOfHalfSpaces();
461 intersectionCone->addHalfSpace(iteHSA.
current());
463 for (iteGNA.
begin(); iteGNA.
end()!=
true; iteGNA.
next()) {
466 intersectionCone->addGenerator(gn);
470 intersectionCone->addHalfSpace(iteHSB.
current());
475 lexmin_ite(intersectionCone->getListOfHalfSpaces());
479 boost::shared_ptr<PolyhedralCone_Rn>,
483 DD(intersectionCone, lexmin_ite, truncationStep);
484 bool notEmpty = !DD.getIsEmpty();
486 std::cout <<
"@@@ nbEDG=" << intersectionCone->numberOfGenerators() <<
"( ";
489 if (notEmpty ==
true && intersectionCone->numberOfGenerators() >= RnDIM) {
490 listOfDualCones_C.push_back(intersectionCone);
491 boost::shared_ptr<Generator_Rn> VX(
new Generator_Rn(RnDIM));
492 VX->makeSum(*LVX_A, *LVX_B);
494 for (
unsigned int k=0; k<RnDIM; k++)
495 std::cout << (*LVX_A)->getCoordinate(k) <<
"+" << (*LVX_B)->getCoordinate(k) <<
"=" << VX->getCoordinate(k) <<
"\t";
510 listOfGenerators_C.push_back(VX);
515 _A2C[a_i].push_back(minkowskiVertexNumber);
516 _B2C[b_j].push_back(minkowskiVertexNumber);
517 ++minkowskiVertexNumber;
520 std::cout <<
")" << std::endl;
529 throw std::domain_error(
"MinkowskiSum::compute() needs two double-description polytopes i.e. with both vertices and half-spaces.");
531 throw std::domain_error(
"MinkowskiSum::compute() needs two same dimension polytopes.");
533 unsigned int lowerBoundIndex1, lowerBoundIndex2, upperBoundIndex1, upperBoundIndex2;
534 double lowerBoundValue = std::numeric_limits< double >::max();
535 double upperBoundValue = std::numeric_limits< double >::min();
541 for (
unsigned int i=0; i<nbVtcesA; ++i) {
542 for (
unsigned int j=0; j<nbVtcesB; ++j) {
545 lowerBoundIndex1 = i;
546 lowerBoundIndex2 = j;
550 upperBoundIndex1 = i;
551 upperBoundIndex2 = j;
560 HS_u->setConstant(
_firstOperand->getGenerator(upperBoundIndex1)->getCoordinate(0) +
_secondOperand->getGenerator(upperBoundIndex2)->getCoordinate(0));
561 HS_l->setConstant(-
_firstOperand->getGenerator(lowerBoundIndex1)->getCoordinate(0) -
_secondOperand->getGenerator(lowerBoundIndex2)->getCoordinate(0));
562 HS_u->setCoefficient(0,-1.);
563 HS_l->setCoefficient(0, 1.);
564 VX_u->setFacet(HS_u);
565 VX_l->setFacet(HS_l);
566 _sum->addGenerator(VX_u);
567 _sum->addGenerator(VX_l);
568 _sum->addHalfSpace(HS_u,
false);
569 _sum->addHalfSpace(HS_l,
false);
600 std::vector< boost::shared_ptr<Generator_Rn> > listOfGenerators_A;
601 std::vector< boost::shared_ptr<Generator_Rn> > listOfGenerators_B;
602 std::vector< boost::shared_ptr<PolyhedralCone_Rn> > listOfDualCones_A;
603 std::vector< boost::shared_ptr<PolyhedralCone_Rn> > listOfDualCones_B;
604 std::vector< std::vector<unsigned int> > neighboursA(
_firstOperand->numberOfGenerators());
606 {
for (
unsigned int i=0; i<
_firstOperand->numberOfGenerators(); ++i) {
607 listOfGenerators_A.push_back(
_firstOperand->getGenerator(i));
608 const boost::shared_ptr<PolyhedralCone_Rn>& cone_a =
_firstOperand->getPrimalCone(i, neighboursA[i]);
609 listOfDualCones_A.push_back( cone_a->computeDualPolyhedralCone() );
611 std::vector< std::vector<unsigned int> > neighboursB(
_secondOperand->numberOfGenerators());
613 {
for (
unsigned int i=0; i<
_secondOperand->numberOfGenerators(); ++i) {
615 const boost::shared_ptr<PolyhedralCone_Rn>& cone_b =
_secondOperand->getPrimalCone(i, neighboursB[i]);
616 listOfDualCones_B.push_back( cone_b->computeDualPolyhedralCone() );
632 boost::numeric::ublas::matrix<double> matOfVtx(
_NF_Vertices.size(), RnDIM);
634 unsigned int vtxNumber=0;
635 std::vector< boost::shared_ptr<Generator_Rn> >::iterator iteVX2;
637 boost::numeric::ublas::matrix_row< boost::numeric::ublas::matrix<double> > matRow(matOfVtx, vtxNumber);
638 std::copy( (*iteVX2)->begin(), (*iteVX2)->end(), matRow.begin());
642 std::vector< std::vector< unsigned int > > VerticesPerFacet;
644 std::vector< boost::shared_ptr<HalfSpace_Rn> > setOfAllHalfSpaces;
645 std::vector< boost::shared_ptr<Generator_Rn> >::iterator iteVX =
_NF_Vertices.begin();
646 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >::iterator itePC =
_NF_Cones.begin();
647 {
for (; itePC!=
_NF_Cones.end(); ++itePC, ++iteVX) {
649 {
for (
unsigned int u=0; u<(*itePC)->numberOfGenerators(); ++u) {
651 boost::shared_ptr<HalfSpace_Rn> HS;
655 for (
unsigned int coord_count=0; coord_count<RnDIM; coord_count++) {
656 double this_coord = (*itePC)->getGenerator(u)->getCoordinate(coord_count);
658 HS->setCoefficient(coord_count, this_coord);
659 sum = sum + this_coord*(*iteVX)->getCoordinate(coord_count);
661 HS->setConstant(-sum);
663 std::vector< unsigned int > vtxStates;
664 double halfSpaceNorm = std::inner_product(HS->begin(), HS->end(), HS->begin(), 0.);
665 halfSpaceNorm = sqrt(halfSpaceNorm);
667 boost::numeric::ublas::vector<double> dist2Hyp = prod(matOfVtx, HS->vect());
671 boost::numeric::ublas::scalar_vector<double> scalsum(
_NF_Vertices.size(),sum);
672 dist2Hyp = dist2Hyp - scalsum;
673 dist2Hyp = dist2Hyp / halfSpaceNorm;;
674 {
for (
unsigned int vtxNumber2=0; vtxNumber2<dist2Hyp.size(); ++vtxNumber2) {
675 if (dist2Hyp(vtxNumber2) > TOL) {
689 vtxStates.push_back(vtxNumber2);
695 {
for (
unsigned int i=0; i<VerticesPerFacet.size() && inserted==
false; ++i) {
696 if (VerticesPerFacet[i].size() == vtxStates.size()) {
697 if (VerticesPerFacet[i] == vtxStates)
700 else if (VerticesPerFacet[i].size() > vtxStates.size()) {
701 if (std::includes(VerticesPerFacet[i].begin(), VerticesPerFacet[i].end(), vtxStates.begin(), vtxStates.end()) ==
true) {
709 if (std::includes(vtxStates.begin(), vtxStates.end(), VerticesPerFacet[i].begin(), VerticesPerFacet[i].end()) ==
true) {
710 VerticesPerFacet[i] = vtxStates;
711 setOfAllHalfSpaces[i] = HS;
717 if (inserted ==
false) {
718 VerticesPerFacet.push_back(vtxStates);
719 setOfAllHalfSpaces.push_back(HS);
727 unsigned int vtxNb=0;
734 bool foundEnoughHS=
false;
736 {
for (
unsigned int i=0; i<VerticesPerFacet.size() && foundEnoughHS==
false; ++i) {
737 {
for (
unsigned int j=0; j<VerticesPerFacet[i].size(); ++j) {
738 if (VerticesPerFacet[i][j] == vtxNb)
741 foundEnoughHS =
true;
744 if (foundEnoughHS ==
true) {
745 _sum->addGenerator( (*iteVX) );
756 {
for (
unsigned int i=0; i<VerticesPerFacet.size(); ++i) {
757 {
for (
unsigned int j=0; j<VerticesPerFacet[i].size(); ++j) {
759 _NF_Vertices[ VerticesPerFacet[i][j] ]->setFacet( setOfAllHalfSpaces[i] );
761 _sum->addHalfSpace( setOfAllHalfSpaces[i],
false);
778 unsigned int currentNumber=0;
779 std::vector< boost::shared_ptr<HalfSpace_Rn> > setOfAllHalfSpaces;
780 std::vector< boost::shared_ptr<Generator_Rn> >::iterator iteVX =
_NF_Vertices.begin();
781 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >::iterator itePC =
_NF_Cones.begin();
783 std::map< boost::shared_ptr<Generator_Rn>,
double > allEdgesNorms;
784 {
for (; itePC!=
_NF_Cones.end(); ++itePC, ++iteVX) {
793 std::vector< unsigned int > c_kMinkowskiVertices;
794 std::vector< unsigned int >::const_iterator iteNgb;
796 {
for (
unsigned int j=0; j<
_neighboursA[a_i].size(); ++j) {
798 {
for (
unsigned int k=0; k<
_A2C[a_i_ngb].size(); ++k) {
800 if (
_A2C[a_i_ngb][k] != currentNumber)
801 c_kMinkowskiVertices.push_back(
_A2C[a_i_ngb][k] );
804 {
for (
unsigned int i=0; i<
_neighboursB[b_j].size(); ++i) {
806 {
for (
unsigned int k=0; k<
_B2C[b_j_ngb].size(); ++k) {
807 if (
_B2C[b_j_ngb][k] != currentNumber)
808 c_kMinkowskiVertices.push_back(
_B2C[b_j_ngb][k] );
814 {
for (
unsigned int u=0; u<(*itePC)->numberOfGenerators(); ++u) {
816 boost::shared_ptr<HalfSpace_Rn> HS;
820 for (
unsigned int coord_count=0; coord_count<RnDIM; coord_count++) {
821 double this_coord = (*itePC)->getGenerator(u)->getCoordinate(coord_count);
823 HS->setCoefficient(coord_count, this_coord);
824 sum = sum + this_coord*(*iteVX)->getCoordinate(coord_count);
826 HS->setConstant(-sum);
827 const boost::shared_ptr<Generator_Rn>& gn1=(*itePC)->getGenerator(u);
828 double gn1_sum2 = std::inner_product(gn1->begin(), gn1->end(), gn1->begin(), 0.);
829 {
for (iteNgb=c_kMinkowskiVertices.begin(); iteNgb!=c_kMinkowskiVertices.end(); ++iteNgb) {
832 {
for (
unsigned int v=0; v<
_NF_Cones[*iteNgb]->numberOfGenerators() && check==
true; ++v) {
833 const boost::shared_ptr<Generator_Rn>& gn2=
_NF_Cones[*iteNgb]->getGenerator(v);
834 double scal_prod = std::inner_product(gn1->begin(), gn1->end(), gn2->begin(), 0.);
835 if (scal_prod > 0.) {
836 double coef1 = scal_prod / gn1_sum2;
838 if (gn1->getNormalDistance(gn2, coef1, RnDIM) < TOL2) {
844 else if (scal_prod > 0.) {
845 double gn2_sum2 = 0.;
847 std::map< boost::shared_ptr<Generator_Rn>,
double >::iterator iteNorm = allEdgesNorms.find( gn2 );
848 if (iteNorm == allEdgesNorms.end())
849 gn2_sum2 = std::inner_product(gn2->begin(), gn2->end(), gn2->begin(), 0.);
851 gn2_sum2 = iteNorm->second;
852 double coef2 = scal_prod / gn2_sum2;
853 if (gn2->getNormalDistance(gn1, coef2, RnDIM) < TOL2) {
857 if (iteNorm != allEdgesNorms.end())
858 allEdgesNorms.erase(iteNorm);
866 (*iteVX)->setFacet(HS);
867 setOfAllHalfSpaces.push_back( HS );
869 (*itePC)->removeGenerator(u);
873 _sum->addGenerator( (*iteVX) );
879 if ((*itePC)->numberOfGenerators() != 0)
880 throw std::domain_error(
"MinkowskiSum::processNormalFan1() dual cones reduction not operational !");
884 std::vector< boost::shared_ptr<HalfSpace_Rn> >::const_iterator iteHS=setOfAllHalfSpaces.begin();
885 {
for (iteHS=setOfAllHalfSpaces.begin(); iteHS!=setOfAllHalfSpaces.end(); ++iteHS) {
887 _sum->addHalfSpace( *iteHS,
false);
896 std::vector< boost::shared_ptr<Generator_Rn> >::iterator iteVX=
_NF_Vertices.begin();
897 std::vector< boost::shared_ptr<PolyhedralCone_Rn> >::iterator itePC=
_NF_Cones.begin();
898 for (; itePC!=
_NF_Cones.end(); ++itePC, ++iteVX) {
904 for (
unsigned int u=0; u<(*itePC)->numberOfGenerators(); u++) {
905 boost::shared_ptr<HalfSpace_Rn> HS;
909 for (
unsigned int coord_count=0; coord_count<RnDIM; coord_count++) {
910 double this_coord = (*itePC)->getGenerator(u)->getCoordinate(coord_count);
912 HS->setCoefficient(coord_count, this_coord);
913 sum = sum + this_coord*(*iteVX)->getCoordinate(coord_count);
915 HS->setConstant(-sum);
918 (*iteVX)->setFacet(
_sum->addHalfSpace(HS,
true));
921 _sum->addGenerator( (*iteVX) );
930 const std::set< unsigned int >& firstOperandCaps,
931 const std::set< unsigned int >& secondOperandCaps,
932 std::set< unsigned int >& sumCaps) {
934 std::cout <<
"PseudoSumWithoutCaps::computeCapHalfSpaces()" << endl;
936 if (
_sum->numberOfGenerators()==0)
937 throw std::domain_error(
"PseudoSumWithoutCaps::computeCapHalfSpaces() We need to compute the Minkowski sum first.");
940 unsigned int facetNumber=0;
941 std::vector< std::vector<unsigned int> > listOfVerticesPerFacet(
_sum->numberOfHalfSpaces());
945 std::cout <<
"facetNumber=" << facetNumber <<
":";
949 for (
unsigned int i=0; i<iteGN.
current()->numberOfFacets(); ++i) {
965 std::vector< std::pair< unsigned int, unsigned int > > thisMinkDecomposition;
966 std::vector< boost::shared_ptr<PolyhedralCone_Rn> > theseNF_Cones;
967 std::vector< boost::shared_ptr<Generator_Rn> > theseNF_Vertices;
980 unsigned int sumFacetNb = 0;
981 std::vector< std::vector<unsigned int> >::const_iterator itVtx = listOfVerticesPerFacet.begin();
982 {
for (; itVtx!=listOfVerticesPerFacet.end(); ++itVtx) {
983 std::set< unsigned int > listOfVtxA, listOfVtxB;
984 std::vector<unsigned int>::const_iterator MinkVtx = itVtx->begin();
986 std::cout << endl <<
"Compute F_A and F_B for facet " << sumFacetNb << endl;
988 {
for (; MinkVtx!=itVtx->end(); ++MinkVtx) {
989 unsigned int MinkNumber = *MinkVtx;
994 std::set<unsigned int> listOfFacetsOfVtxA;
995 std::set<unsigned int> tmpInterResForA, tmp2InterResForA;
996 std::set<unsigned int>::const_iterator itVtxNbOperand;
997 itVtxNbOperand = listOfVtxA.begin();
998 for (
unsigned int ngb_count=0; ngb_count<
_firstOperand->getGenerator(*itVtxNbOperand)->numberOfFacets(); ngb_count++) {
999 boost::shared_ptr<HalfSpace_Rn> Fi =
_firstOperand->getGenerator(*itVtxNbOperand)->getFacet(ngb_count);
1000 listOfFacetsOfVtxA.insert(
_firstOperand->getHalfSpaceNumber(Fi));
1004 std::cout <<
"F_A:";
1005 std::cout <<
" V = {";
1006 std::cout <<
" " << *itVtxNbOperand;
1008 tmpInterResForA = listOfFacetsOfVtxA;
1010 {
for (; itVtxNbOperand!=listOfVtxA.end(); ++itVtxNbOperand) {
1012 std::cout <<
" " << *itVtxNbOperand;
1014 std::set<unsigned int> curListOfFacetsOfVtxA;
1015 for (
unsigned int ngb_count=0; ngb_count<
_firstOperand->getGenerator(*itVtxNbOperand)->numberOfFacets(); ngb_count++) {
1016 boost::shared_ptr<HalfSpace_Rn> Fi =
_firstOperand->getGenerator(*itVtxNbOperand)->getFacet(ngb_count);
1017 curListOfFacetsOfVtxA.insert(
_firstOperand->getHalfSpaceNumber(Fi));
1019 tmp2InterResForA = tmpInterResForA;
1020 tmpInterResForA.clear();
1021 std::set_intersection(
1022 tmp2InterResForA.begin(),
1023 tmp2InterResForA.end(),
1024 curListOfFacetsOfVtxA.begin(),
1025 curListOfFacetsOfVtxA.end(),
1026 std::inserter(tmpInterResForA, tmpInterResForA.end()));
1027 if (listOfFacetsOfVtxA.empty() ==
true)
1028 throw std::domain_error(
"PseudoSumWithoutCaps::computeCapHalfSpaces() the i-Face of polytope A has 0 half-space.");
1034 std::set<unsigned int> InterResForA;
1035 std::set_intersection(
1036 tmpInterResForA.begin(),
1037 tmpInterResForA.end(),
1038 firstOperandCaps.begin(),
1039 firstOperandCaps.end(),
1040 std::inserter(InterResForA, InterResForA.end()));
1042 std::cout <<
" ; H = { ";
1043 std::copy(InterResForA.begin(), InterResForA.end(), std::ostream_iterator<unsigned int>(std::cout,
" ") );
1049 if (InterResForA.empty() !=
true)
1050 sumCaps.insert( sumFacetNb );
1056 std::set<unsigned int> listOfFacetsOfVtxB;
1057 std::set<unsigned int> tmpInterResForB, tmp2InterResForB;
1058 itVtxNbOperand = listOfVtxB.begin();
1059 for (
unsigned int ngb_count=0; ngb_count<
_secondOperand->getGenerator(*itVtxNbOperand)->numberOfFacets(); ngb_count++) {
1060 boost::shared_ptr<HalfSpace_Rn> Fi =
_secondOperand->getGenerator(*itVtxNbOperand)->getFacet(ngb_count);
1061 listOfFacetsOfVtxB.insert(
_secondOperand->getHalfSpaceNumber(Fi));
1064 std::cout <<
"F_B:";
1065 std::cout <<
" V = {";
1066 std::cout <<
" " << *itVtxNbOperand;
1068 tmpInterResForB = listOfFacetsOfVtxB;
1070 {
for (; itVtxNbOperand!=listOfVtxB.end(); ++itVtxNbOperand) {
1072 std::cout <<
" " << *itVtxNbOperand;
1074 std::set<unsigned int> curListOfFacetsOfVtxB;
1075 for (
unsigned int ngb_count=0; ngb_count<
_secondOperand->getGenerator(*itVtxNbOperand)->numberOfFacets(); ngb_count++) {
1076 boost::shared_ptr<HalfSpace_Rn> Fi =
_secondOperand->getGenerator(*itVtxNbOperand)->getFacet(ngb_count);
1077 curListOfFacetsOfVtxB.insert(
_secondOperand->getHalfSpaceNumber(Fi));
1079 tmp2InterResForB = tmpInterResForB;
1080 tmpInterResForB.clear();
1081 std::set_intersection(
1082 tmp2InterResForB.begin(),
1083 tmp2InterResForB.end(),
1084 curListOfFacetsOfVtxB.begin(),
1085 curListOfFacetsOfVtxB.end(),
1086 std::inserter(tmpInterResForB, tmpInterResForB.end()));
1087 if (listOfFacetsOfVtxB.empty() ==
true)
1088 throw std::domain_error(
"PseudoSumWithoutCaps::computeCapHalfSpaces() the j-Face of polytope B has 0 half-space.");
1094 std::set<unsigned int> InterResForB;
1095 std::set_intersection(
1096 tmpInterResForB.begin(),
1097 tmpInterResForB.end(),
1098 secondOperandCaps.begin(),
1099 secondOperandCaps.end(),
1100 std::inserter(InterResForB, InterResForB.end()));
1102 std::cout <<
" ; H = { ";
1103 std::copy(InterResForB.begin(), InterResForB.end(), std::ostream_iterator<unsigned int>(std::cout,
" ") );
1110 if (InterResForB.empty() !=
true)
1111 sumCaps.insert( sumFacetNb );
1121 const std::set<unsigned int>& firstOperandCaps,
1122 const std::set<unsigned int>& secondOperandCaps,
1123 std::set<unsigned int>& newCaps,
1126 if (
_sum->numberOfHalfSpaces() == 0 ||
_sum->numberOfGeneratorsPerFacet() == 0)
1127 throw std::domain_error(
"PseudoSumWithoutCaps::rebuildSum() _sum is not computed.");
1129 std::set< unsigned int > sumCaps;
1132 std::cout <<
"firstOperandCaps=" << firstOperandCaps.size() << std::endl;
1133 std::cout <<
"secondOperandCaps=" << secondOperandCaps.size() << std::endl;
1134 std::cout <<
"sumCaps=" << sumCaps.size() << std::endl;
1138 boost::shared_ptr<Polytope_Rn> newSum;
1140 newSum->createBoundingBox(bb_size);
1141 std::vector< boost::shared_ptr<HalfSpace_Rn> > tryCapsForNewSum;
1144 for (iteHS1.
begin(); iteHS1.
end()!=
true; iteHS1.
next()) {
1145 tryCapsForNewSum.push_back(iteHS1.
current());
1149 for (iteHS2.
begin(); iteHS2.
end()!=
true; iteHS2.
next()) {
1151 newSum->addHalfSpace(iteHS2.
current());
1155 if (bb_size == 0.) {
1167 boost::shared_ptr<PolyhedralCone_Rn>,
1170 DD(newSum, lexmin_ite, truncationStep);
1174 for (iteHS3.
begin(); iteHS3.
end()!=
true; iteHS3.
next()) {
1175 std::vector< boost::shared_ptr<HalfSpace_Rn> >::const_iterator iteCaps = tryCapsForNewSum.begin();
1176 for (; iteCaps!=tryCapsForNewSum.end(); ++iteCaps) {
1177 if (iteHS3.
current() == *iteCaps) {
1191 const boost::shared_ptr<Polytope_Rn>& A,
1192 const boost::shared_ptr<Polytope_Rn>& B,
1193 boost::shared_ptr<Polytope_Rn>& C,
1194 const std::set< unsigned int >& firstOperandCaps,
1195 const std::set< unsigned int >& secondOperandCaps,
1196 std::set< unsigned int >& newCaps,
1201 C->createBoundingBox(bb_size);
1202 std::vector< boost::shared_ptr<HalfSpace_Rn> > RnCaps;
1205 for (iteHS0.
begin(); iteHS0.
end()!=
true; iteHS0.
next()) {
1206 RnCaps.push_back(iteHS0.
current());
1210 for (iteHS1.
begin(); iteHS1.
end()!=
true; iteHS1.
next()) {
1212 C->addHalfSpace(iteHS1.
current());
1216 for (iteHS2.
begin(); iteHS2.
end()!=
true; iteHS2.
next()) {
1218 C->addHalfSpace(iteHS2.
current());
1227 boost::shared_ptr<PolyhedralCone_Rn>,
1230 DD(C, lexmin_ite, truncationStep);
1235 for (iteHS3.
begin(); iteHS3.
end()!=
true; iteHS3.
next()) {
1236 std::vector< boost::shared_ptr<HalfSpace_Rn> >::const_iterator iteCaps = RnCaps.begin();
1237 for (; iteCaps!=RnCaps.end(); ++iteCaps) {
1238 if (iteHS3.
current() == *iteCaps) {
1249 if (pol->numberOfGenerators() != 0) {
1251 {
for (iteGN.
begin(); iteGN.
end()!=
true; iteGN.
next()) {
1252 const boost::shared_ptr<Generator_Rn>& v2_A = iteGN.
current();
1253 boost::numeric::ublas::vector<double> coord = v2_A->vect() + v2t;
1254 v2_A->setCoordinates(coord);
1257 if (pol->numberOfHalfSpaces() != 0) {
1259 {
for (iteHS.
begin(); iteHS.
end()!=
true; iteHS.
next()) {
1260 const boost::shared_ptr<HalfSpace_Rn>& hs = iteHS.
current();
1261 double prod = std::inner_product(hs->begin(), hs->end(), v2t.begin(), 0.);
1262 hs->setConstant( hs->getConstant()-prod );
1269 if (pol->numberOfGenerators() != 0) {
1270 for (
unsigned int i=0; i<gravity_center.size (); ++i)
1271 gravity_center(i) = 0.;
1273 {
for (iteGN.
begin(); iteGN.
end()!=
true; iteGN.
next()) {
1274 gravity_center += iteGN.
current()->vect();
1276 gravity_center /= pol->numberOfGenerators();
1279 throw std::domain_error(
"TopGeomTools::GravityCenter() the polytope already does not have generators.");
1285 double maxDistance = 0.;
1286 double currentConstant = -1.;
1287 {
for (iteHS_B.
begin(); iteHS_B.
end()!=
true; iteHS_B.
next()) {
1288 double halfSpaceNorm = std::inner_product(iteHS_B.
current()->begin(), iteHS_B.
current()->end(), iteHS_B.
current()->begin(), 0.);
1289 halfSpaceNorm = sqrt(halfSpaceNorm);
1291 {
for (iteGN_A.
begin(); iteGN_A.
end()!=
true; iteGN_A.
next()) {
1292 double scalarProduct = std::inner_product(iteGN_A.
current()->begin(), iteGN_A.
current()->end(), iteHS_B.
current()->begin(), 0.);
1293 double distanceToHyperplane = (scalarProduct + iteHS_B.
current()->getConstant()) / halfSpaceNorm;
1296 if (fabs(distanceToHyperplane) > maxDistance) {
1297 maxDistance = fabs(distanceToHyperplane);
1298 currentConstant = iteHS_B.
current()->getConstant();
1304 sfactor = (currentConstant + maxDistance) / currentConstant;
1306 throw std::domain_error(
"TopGeomTools::computeScalingFactorForInclusion() pol2 should contain the origin to compute the scaling factor.");
1313 throw std::domain_error(
"TopGeomTools::scalingFactor() scaling factor too small.");
1314 if (pol->numberOfGenerators() != 0) {
1317 iteGN.
current()->scalingFactor(factor);
1319 if (pol->numberOfHalfSpaces() != 0) {
1322 iteHS.
current()->setConstant(iteHS.
current()->getConstant()*factor);
1329 throw std::domain_error(
"TopGeomTools::scalingFactor() scaling factor too small.");
1330 if (pol->numberOfGenerators() != 0) {
1333 iteGN.
current()->scalingFactor(factor);
1335 if (pol->numberOfHalfSpaces() != 0) {
1338 iteHS.
current()->setConstant(iteHS.
current()->getConstant()*factor);
1344 const std::set< unsigned int >& listOfHyperplanes,
1345 const boost::shared_ptr<Polytope_Rn>& original_pol,
1346 boost::shared_ptr<Polytope_Rn>& proj_pol) {
1349 if (listOfHyperplanes.empty()==
true || listOfHyperplanes.size()>
Rn::getDimension())
1350 throw std::invalid_argument(
"TopGeomTools::projectPolytopeOnCanonicalHyperplanes() wrong list of hyperplanes to project");
1351 unsigned int projectedDimension = listOfHyperplanes.size();
1356 std::vector< boost::shared_ptr<Generator_Rn> > newArrayOfGN;
1358 {
for (iteGN.
begin(); iteGN.
end()!=
true; iteGN.
next()) {
1360 boost::shared_ptr<Generator_Rn> VX;
1362 for (
unsigned int i=1; i<=currentDimension; ++i) {
1363 if (listOfHyperplanes.find(i) != listOfHyperplanes.end()) {
1365 VX->setCoordinate(j, iteGN.
current()->getCoordinate(i-1));
1369 bool foundEqual =
false;
1370 std::vector< boost::shared_ptr<Generator_Rn> >::const_iterator iteNew = newArrayOfGN.begin();
1371 for ( ; iteNew != newArrayOfGN.end() && foundEqual ==
false; ++iteNew) {
1375 if (foundEqual ==
false)
1376 newArrayOfGN.push_back( VX );
1379 std::vector< boost::shared_ptr<Generator_Rn> >::const_iterator iteNew2 = newArrayOfGN.begin();
1380 for ( ; iteNew2 != newArrayOfGN.end(); ++iteNew2)
1381 proj_pol->addGenerator(*iteNew2);
1384 proj_pol->checkTopologyAndGeometry();
1391 const std::set< unsigned int >& originalSpaceDirections,
1392 unsigned int totalSpaceDimension,
1393 const boost::shared_ptr<Polytope_Rn>& original_polytope,
1394 boost::shared_ptr<PolyhedralCone_Rn>& extruded_polyhedron) {
1397 if (originalSpaceDirections.empty()==
true || originalSpaceDirections.size()>
Rn::getDimension())
1398 throw std::invalid_argument(
"TopGeomTools::extrudeInCanonicalDirections() wrong definition of the original space");
1405 {
for (iteHS.
begin(); iteHS.
end()!=
true; iteHS.
next()) {
1406 boost::shared_ptr<HalfSpace_Rn> newHS;
1408 newHS->setConstant(iteHS.
current()->getConstant());
1409 unsigned int shift = 0;
1410 for (
unsigned int i=1; i<=totalSpaceDimension; ++i) {
1412 if (originalSpaceDirections.find(i) != originalSpaceDirections.end()) {
1413 newHS->setCoefficient(i-1, iteHS.
current()->getCoefficient(i-shift-1));
1416 newHS->setCoefficient(i-1, 0.);
1420 extruded_polyhedron->addHalfSpace(newHS);
1429 const boost::shared_ptr<Polytope_Rn>& original_pol,
1430 boost::shared_ptr<Polytope_Rn>& polar_pol,
1431 bool forceComputation,
double bb_size) {
1433 unsigned int dim = original_pol->dimension();
1436 if (original_pol->numberOfGenerators() != 0 && original_pol->numberOfHalfSpaces() != 0 && forceComputation ==
false) {
1437 std::vector< std::vector< unsigned int > > listOfGeneratorsPerFacet;
1438 original_pol->getGeneratorsPerFacet(listOfGeneratorsPerFacet);
1440 std::vector< boost::shared_ptr<HalfSpace_Rn> > listOfNewHalfSpaces;
1441 std::vector< double > listOfLinearConstraintNorms;
1446 boost::shared_ptr<HalfSpace_Rn> HS;
1448 HS->setConstant(1.);
1449 boost::numeric::ublas::vector< double >::const_iterator iteCoord = iteGN.
current()->begin();
1450 unsigned int coord_count = 0;
1452 for ( ; iteCoord != iteGN.
current()->end(); ++iteCoord ) {
1453 HS->setCoefficient(coord_count, *iteCoord);
1458 polar_pol->addHalfSpace(HS);
1459 listOfNewHalfSpaces.push_back(HS);
1460 double halfSpaceNorm = std::inner_product(HS->begin(), HS->end(), HS->begin(), 0.);
1461 listOfLinearConstraintNorms.push_back(sqrt(halfSpaceNorm));
1470 if (iteHS.
current()->getConstant() < TOL)
1471 throw std::invalid_argument(
"TopGeomTools::PolarPolytope() the input polytope should contain the origin.");
1472 boost::numeric::ublas::vector<double> copyOfHSCoef(iteHS.
current()->vect());
1474 copyOfHSCoef = copyOfHSCoef / iteHS.
current()->getConstant();
1475 boost::shared_ptr<Generator_Rn> GN;
1477 GN->setCoordinates(copyOfHSCoef);
1480 unsigned int nbON = 0;
1481 bool pointIsOUT =
false;
1482 for (
unsigned int u=0; u<polar_pol->numberOfHalfSpaces(); ++u) {
1484 bool isRegularFacet =
false;
1486 if (std::find(listOfGeneratorsPerFacet[gnNb].begin(), listOfGeneratorsPerFacet[gnNb].end(), u) != listOfGeneratorsPerFacet[gnNb].end() )
1487 isRegularFacet =
true;
1488 HalfSpace_Rn::State currentState = polar_pol->checkPoint(GN, listOfNewHalfSpaces[u], listOfLinearConstraintNorms[u]);
1494 GN->setFacet( listOfNewHalfSpaces[u] );
1495 if (isRegularFacet ==
true)
1499 if (isRegularFacet ==
true)
1504 if (isRegularFacet ==
true)
1505 GN->setFacet( listOfNewHalfSpaces[u] );
1509 if (pointIsOUT ==
true || nbON < dim) {
1514 boost::numeric::ublas::matrix<double> A(dim,dim);
1515 boost::numeric::ublas::vector<double> x(dim);
1516 boost::numeric::ublas::permutation_matrix<double> pm(A.size1());
1518 for (
unsigned int j=0; j<dim; ++j) {
1519 const boost::numeric::ublas::vector<double>& hyperplane = listOfNewHalfSpaces[ listOfGeneratorsPerFacet[gnNb][j] ]->vect();
1520 boost::numeric::ublas::matrix_row< boost::numeric::ublas::matrix<double> > A_row_j(A, j);
1521 A_row_j = hyperplane;
1522 x(j) = -listOfNewHalfSpaces[ listOfGeneratorsPerFacet[gnNb][j] ]->getConstant();
1526 int res = boost::numeric::ublas::lu_factorize(A, pm);
1528 boost::numeric::ublas::lu_substitute(A, pm, x);
1529 GN->setCoordinates(x);
1532 polar_pol->addGenerator(GN);
1538 if (original_pol->numberOfGenerators() != 0) {
1542 boost::shared_ptr<HalfSpace_Rn> HS;
1544 HS->setConstant(1.);
1545 boost::numeric::ublas::vector< double >::const_iterator iteCoord = iteGN.
current()->begin();
1546 unsigned int coord_count = 0;
1548 for ( ; iteCoord != iteGN.
current()->end(); ++iteCoord ) {
1550 HS->setCoefficient(coord_count, *iteCoord);
1555 polar_pol->addHalfSpace(HS);
1563 if (forceComputation ==
true) {
1565 polar_pol->createBoundingBox(bb_size);
1569 unsigned int truncationStep = 2*dim;
1571 boost::shared_ptr<PolyhedralCone_Rn>,
1574 DD(polar_pol, lexmin_ite, truncationStep);
1576 catch(invalid_argument& except) {
1577 cerr <<
"Invalid argument exception in TopGeomTools::PolarPolytope() " << except.what() << endl;
1580 catch(out_of_range& except) {
1581 cerr <<
"Out of range exception in TopGeomTools::PolarPolytope() " << except.what() << endl;
1584 catch(ios_base::failure& except) {
1585 cerr <<
"In/out exception in TopGeomTools::PolarPolytope() " << except.what() << endl;
1588 catch(logic_error& except) {
1589 cerr <<
"Logic error exception in TopGeomTools::PolarPolytope() " << except.what() << endl;
1593 cerr <<
"Unexpected exception caught in TopGeomTools::PolarPolytope() !" << endl;
1601 if (original_pol->numberOfHalfSpaces() != 0) {
1605 if (iteHS.
current()->getConstant() < TOL)
1606 throw std::invalid_argument(
"TopGeomTools::PolarPolytope() the input polytope should contain the origin.");
1607 boost::numeric::ublas::vector<double> copyOfHSCoef(iteHS.
current()->vect());
1609 copyOfHSCoef = copyOfHSCoef / iteHS.
current()->getConstant();
1610 boost::shared_ptr<Generator_Rn> GN;
1612 GN->setCoordinates(copyOfHSCoef);
1624 polar_pol->addGenerator(GN);
1635 unsigned int dim = pol->dimension();
1637 if (pol->numberOfHalfSpaces() != 0)
1638 throw std::domain_error(
"DoubleDescriptionFromGenerators::Compute() the polytope already has half-spaces.");
1639 if (pol->numberOfGenerators() == 0)
1640 throw std::domain_error(
"DoubleDescriptionFromGenerators::Compute() the polytope does not have generators.");
1649 boost::numeric::ublas::vector<double> gravity_center(dim);
1654 if (norm_2(gravity_center) > TOL)
1658 boost::shared_ptr<Polytope_Rn> polar_pol(
new Polytope_Rn());
1668 if (norm_2(gravity_center) > TOL)
1683 throw std::domain_error(
"Visualization::gnuplot(std::ostream& out) dimension is not 2 ");
1684 out <<
"set object " << name <<
" polygon from ";
1685 boost::shared_ptr<HalfSpace_Rn> oldHS;
1686 boost::shared_ptr<Generator_Rn> startVTX,referenceVTX;
1689 std::set< boost::shared_ptr<Generator_Rn> > alreadyProcessedVTX;
1690 {
for (LVX_A.
begin(); LVX_A.
end()!=
true; LVX_A.
next()) {
1691 if (alreadyProcessedVTX.find(LVX_A.
current()) == alreadyProcessedVTX.end()) {
1692 referenceVTX = LVX_A.
current();
1693 alreadyProcessedVTX.insert(referenceVTX);
1694 boost::shared_ptr<HalfSpace_Rn> referenceHS = referenceVTX->getFacet(0);
1695 if (referenceHS == oldHS)
1696 referenceHS = referenceVTX->getFacet(1);
1698 out << LVX_A.
current()->getCoordinate(0) <<
"," << LVX_A.
current()->getCoordinate(1) <<
" to ";
1700 {
for (LVX_B.
begin(); LVX_B.
end()!=
true; LVX_B.
next()) {
1701 if (alreadyProcessedVTX.find(LVX_B.
current()) == alreadyProcessedVTX.end()) {
1702 if (referenceHS == LVX_B.
current()->getFacet(0)) {
1703 referenceHS = referenceVTX->getFacet(1);
1705 out << LVX_B.
current()->getCoordinate(0) <<
"," << LVX_B.
current()->getCoordinate(1) <<
" to ";
1706 referenceVTX = LVX_B.
current();
1707 alreadyProcessedVTX.insert(referenceVTX);
1709 else if (referenceHS == LVX_B.
current()->getFacet(1)) {
1710 referenceHS = referenceVTX->getFacet(0);
1712 out << LVX_B.
current()->getCoordinate(0) <<
"," << LVX_B.
current()->getCoordinate(1) <<
" to ";
1713 referenceVTX = LVX_B.
current();
1714 alreadyProcessedVTX.insert(referenceVTX);
1720 out << startVTX->getCoordinate(0) <<
"," << startVTX->getCoordinate(1);
1721 out <<
" lc palette " << col << std::endl;
1730 bool operator() (std::pair< double, NormedHS > pt1, std::pair< double, NormedHS > pt2) {
return (pt1.first < pt2.first);}
1738 bool operator() (std::pair< double, NormedHS > pt1, std::pair< double, NormedHS > pt2) {
return (pt1.second.getConstant() < pt2.second.getConstant());}
1743 unsigned int RnDIM = pol->dimension();
1745 std::vector< std::pair<double, NormedHS > > listOfNormedVectors;
1747 for (
unsigned int idx=0; idx<pol->numberOfHalfSpaces(); ++idx) {
1748 double distance = norm_2(pol->getHalfSpace(idx)->vect());
1749 if (distance > 0.000001) {
1750 NormedHS NV(pol->getHalfSpace(idx)->vect() / distance, pol->getHalfSpace(idx)->getConstant() / distance, idx);
1751 listOfNormedVectors.push_back( std::make_pair(-1., NV) );
1786 std::vector< std::pair< double, NormedHS > >::iterator thisIte = listOfNormedVectors.begin();
1787 for (; thisIte<listOfNormedVectors.end(); ++thisIte)
1788 listOfHS.
push_back( pol->getHalfSpace( thisIte->second.getNumberOfNormedHS() ) );
1790 pol->setListOfHalfSpaces(listOfHS);