21 #include <boost/shared_ptr.hpp>
22 #include <boost/timer.hpp>
37 static void setCheckGeneratorsTest(
bool b) {_checkGeneratorsTest = b;}
40 static bool getCheckGeneratorsTest() {
return _checkGeneratorsTest;}
43 static void setCheckGeneratorsValue(
unsigned int d) {_checkGeneratorsValue = d;}
46 static unsigned int getCheckGeneratorsValue() {
return _checkGeneratorsValue;}
49 static bool _checkGeneratorsTest;
50 static unsigned int _checkGeneratorsValue;
55 bool RunOptions::_checkGeneratorsTest =
false;
56 unsigned int RunOptions::_checkGeneratorsValue = 0;
59 int main(
int argc,
char* argv[]) {
61 unsigned int dimension = 0;
64 std::string fileName1,fileName2;
65 bool boundingBox =
true;
66 bool boundingVolume =
false;
67 double boundingSize = 1000;
68 double volumeOfPolytope = -1.;
69 unsigned int facetsToCheck = 0, generatorsToCheck = 0;
70 int vertexToComputeDistances=-1, facetToComputeDistances=-1;
71 bool computeDistances=
false;
72 bool p1=
false, p2=
false, c1=
false, c2=
false;
73 bool COMPUTE_VOL=
false, SUBSET=
false, BOUNDS=
false, POLAR=
false;
74 bool INTER=
false, CHCK_EQ=
false, MS=
false, check_all=
false, output=
false;
75 std::string outputFileName;
77 std::ostringstream stream_;
78 stream_ <<
"Version ";
84 std::string version = stream_.str();
87 for(
int i = 1; i < argc; ++i) {
88 if (strcmp(argv[i],
"-p1") == 0 || strcmp(argv[i],
"--polytope1") == 0) {
90 cerr <<
"Invalid file " << argv[i] << std::endl;
94 char* fileName_1 = argv[++i];
95 std::string file1(fileName_1);
99 else if (strcmp(argv[i],
"-p2") == 0 || strcmp(argv[i],
"--polytope2") == 0) {
101 cerr <<
"Invalid file " << argv[i] << std::endl;
104 char* fileName_2 = argv[++i];
105 std::string file2(fileName_2);
109 else if (strcmp(argv[i],
"-o") == 0 || strcmp(argv[i],
"--output") == 0) {
111 cerr <<
"Invalid file " << argv[i] << std::endl;
114 char* fileName_3 = argv[++i];
115 std::string file3(fileName_3);
116 outputFileName = file3;
119 else if (strcmp(argv[i],
"-c1") == 0 || strcmp(argv[i],
"--polyhedralcone1") == 0) {
121 cerr <<
"Invalid file " << argv[i] << std::endl;
125 char* fileName_1 = argv[++i];
126 std::string file1(fileName_1);
130 else if (strcmp(argv[i],
"-c2") == 0 || strcmp(argv[i],
"--polyhedralcone2") == 0) {
132 cerr <<
"Invalid file " << argv[i] << std::endl;
135 char* fileName_2 = argv[++i];
136 std::string file2(fileName_2);
140 else if (strcmp(argv[i],
"-v") == 0 || strcmp(argv[i],
"--version") == 0) {
141 cout << version << std::endl;
144 else if (strcmp(argv[i],
"-ch") == 0 || strcmp(argv[i],
"--check-all") == 0) {
148 else if (strcmp(argv[i],
"-MS") == 0 || strcmp(argv[i],
"--MinkowskiSum") == 0) {
156 else if (strcmp(argv[i],
"-IN") == 0 || strcmp(argv[i],
"--Intersection") == 0) {
164 else if (strcmp(argv[i],
"-PO") == 0 || strcmp(argv[i],
"--Polar") == 0) {
172 else if (strcmp(argv[i],
"-SS") == 0 || strcmp(argv[i],
"--Subset") == 0) {
179 else if (strcmp(argv[i],
"-EQ") == 0 || strcmp(argv[i],
"--Equality") == 0) {
187 else if (strcmp(argv[i],
"-bb") == 0 || strcmp(argv[i],
"--boundingbox") == 0) {
189 cerr <<
"Invalid bounding box dimension " << argv[i] << std::endl;
194 boundingVolume =
true;
195 boundingSize = atof(argv[++i]);
197 else if (strcmp(argv[i],
"-bs") == 0 || strcmp(argv[i],
"--boundingsimplex") == 0) {
199 cerr <<
"Invalid bounding simplex dimension " << argv[i] << std::endl;
205 boundingVolume =
true;
206 boundingSize = atof(argv[++i]);
208 else if (strcmp(argv[i],
"-d") == 0 || strcmp(argv[i],
"--dimension") == 0) {
210 cerr <<
"Invalid cartesian space dimension " << argv[i] << std::endl;
213 dimension = atoi(argv[++i]);
216 else if (strcmp(argv[i],
"-t") == 0 || strcmp(argv[i],
"--tolerance") == 0) {
218 cerr <<
"Invalid cartesian space tolerance " << argv[i] << std::endl;
221 tolerance = atof(argv[++i]);
224 else if (strcmp(argv[i],
"-VO") == 0 || strcmp(argv[i],
"--Volume") == 0) {
228 else if (strcmp(argv[i],
"-cg") == 0 || strcmp(argv[i],
"--check-generators") == 0) {
230 cerr <<
"Invalid number of generators to check " << argv[i] << std::endl;
233 generatorsToCheck = atoi(argv[++i]);
234 RunOptions::setCheckGeneratorsTest(
true);
235 RunOptions::setCheckGeneratorsValue(generatorsToCheck);
237 else if (strcmp(argv[i],
"-cf") == 0 || strcmp(argv[i],
"--check-facets") == 0) {
239 cerr <<
"Invalid number of facets to check " << argv[i] << std::endl;
242 facetsToCheck = atoi(argv[++i]);
243 RunOptions::setCheckGeneratorsTest(
true);
244 RunOptions::setCheckGeneratorsValue(generatorsToCheck);
246 else if (strcmp(argv[i],
"--generator") == 0) {
248 cerr <<
"Invalid number of generator " << argv[i] << std::endl;
251 vertexToComputeDistances = atoi(argv[++i]);
252 computeDistances =
true;
257 else if (strcmp(argv[i],
"--facet") == 0) {
259 cerr <<
"Invalid number of facet " << argv[i] << std::endl;
262 facetToComputeDistances = atoi(argv[++i]);
263 computeDistances =
true;
268 else if (strcmp(argv[i],
"--Bounds") == 0) {
271 else if (strcmp(argv[i],
"-h") == 0 || strcmp(argv[i],
"--help") == 0) {
272 cout << version << std::endl;
273 cout <<
"\t-d [--dimension] ARG\t:\tSet the cartesian space dimension" << std::endl;
274 cout <<
"\t-t [--tolerance] ARG\t:\tSet the cartesian space tolerance [default: 1.e-06]" << std::endl;
275 cout <<
"\t-o [--output] ARG\t:\tThe optional output file (ptop or pcon extension)" << std::endl;
276 cout <<
"\t-p1 [--polytope1] ARG\t:\tFirst polytope input file (ptop extension)" << std::endl;
277 cout <<
"\t-p2 [--polytope2] ARG\t:\tSecond polytope input file (ptop extension)" << std::endl;
278 cout <<
"\t-c1 [--polyhedralcone1] ARG\t:\tFirst polyhedral cone input file (pcon extension)" << std::endl;
279 cout <<
"\t-c2 [--polyhedralcone2] ARG\t:\tSecond polyhedral cone input file (pcon extension)" << std::endl;
280 cout <<
"\t-cf [--check-facets] ARG\t:\tUsed to test when we know the final number of facets" << std::endl;
281 cout <<
"\t-cg [--check-generators] ARG\t:\tUsed to test when we know the final number of generators" << std::endl;
282 cout <<
"\t-bs [--boundingsimplex] ARG\t:\tBounding simplex size, containing the bounding box -bb (n+1 vertices)" << std::endl;
283 cout <<
"\t-bb [--boundingbox] ARG\t:\tBounding box size centered on the origin including the polytope (2^n vertices)" << std::endl;
284 cout <<
"\t-ch [--check-all]\t\t:\tUsed to perform all tests (no arguments, can be slow)." << std::endl;
285 cout <<
"\t-MS [--MinkowskiSum] \t:\tSet the option to turn on Minkowski sums" << std::endl;
286 cout <<
"\t-IN [--Intersection] \t:\tSet the option to turn on intersections (default option)" << std::endl;
287 cout <<
"\t-SS [--Subset] \t:\tSet the option to test whether P1 is included in P2" << std::endl;
288 cout <<
"\t-VO [--Volume] \t:\tSet the option to turn on the volume computation for the polytope" << std::endl;
289 cout <<
"\t-EQ [--Equality] \t:\tSet the option to turn on the equality check between ptop or pcon" << std::endl;
290 cout <<
"\t-v [--version]\t\t\t:\tGive the current version" << std::endl;
294 cerr <<
"Unknown option " << argv[i] << std::endl;
300 cerr <<
"Dimension has not been set." << std::endl;
306 if (c2 ==
true || p2 ==
true)
307 if (MS ==
false && CHCK_EQ ==
false && SUBSET ==
false)
310 int truncationStep = 0;
311 boost::shared_ptr<PolyhedralCone_Rn> A;
312 boost::shared_ptr<PolyhedralCone_Rn> B;
313 boost::shared_ptr<PolyhedralCone_Rn> C;
319 if (boundingVolume ==
true) {
320 if (A->numberOfGenerators() == 0) {
322 if (boundingBox ==
true) {
324 A->createBoundingBox(boundingSize);
328 A->createBoundingSimplex(boundingSize);
332 boost::shared_ptr<Polytope_Rn> PA = boost::dynamic_pointer_cast<Polytope_Rn>(A);
334 if (check_all ==
true)
335 PA->checkTopologyAndGeometry();
336 std::string FileOut(
"output");
337 FileOut += fileName1;
339 FileOut = outputFileName;
359 catch(std::ios_base::failure& e) {
360 cerr <<
"In/out exception: " << e.what() << std::endl;
364 if ((p1==
true && p2==
true) || (c1==
true && c2==
true)) {
365 if (p1==
true && p2==
true) {
371 {
for (
unsigned int i=0; i<A->numberOfGenerators(); i++) {
372 C->addGenerator(A->getGenerator(i));
375 for (iteHSA.
begin(); iteHSA.
end()!=
true; iteHSA.
next()) {
376 C->addHalfSpace(iteHSA.
current());
379 for (iteHSB.
begin(); iteHSB.
end()!=
true; iteHSB.
next()) {
380 C->addHalfSpace(iteHSB.
current());
382 truncationStep = A->numberOfHalfSpaces();
384 else if ((p1==
true && p2!=
true) || (c1==
true && c2!=
true)) {
389 cerr <<
"This program needs at least one polytope or one polyhedral cone and no mix between them." << std::endl;
393 boost::timer this_timer;
396 if ((MS ==
true) || (INTER ==
true) || (COMPUTE_VOL ==
true) || (SUBSET ==
true) || (POLAR ==
true)) {
399 if (p1!=
true || p2!=
true) {
400 cout <<
"ERROR 2 polytopes are needed to compute the minkowski sum." << std::endl;
414 boost::shared_ptr<Polytope_Rn> PA = boost::dynamic_pointer_cast<Polytope_Rn>(A);
415 boost::shared_ptr<Polytope_Rn> PB = boost::dynamic_pointer_cast<Polytope_Rn>(B);
416 boost::shared_ptr<Polytope_Rn> PC = boost::dynamic_pointer_cast<Polytope_Rn>(C);
420 else if (COMPUTE_VOL ==
true) {
421 boost::shared_ptr<Polytope_Rn> Pol = boost::dynamic_pointer_cast<Polytope_Rn>(C);
424 cout <<
"VolumeOfPolytope=" << volumeOfPolytope << std::endl;
427 else if (POLAR ==
true) {
428 boost::shared_ptr<Polytope_Rn> Pol = boost::dynamic_pointer_cast<Polytope_Rn>(C);
429 boost::shared_ptr<Polytope_Rn> result;
433 std::string FileOut(
"output");
434 FileOut += fileName1;
436 FileOut = outputFileName;
440 else if (SUBSET ==
true) {
441 bool isInside = A->isIncluded(B);
442 std::string answer = (isInside ==
true) ?
"" :
"not";
443 cout <<
"P1 is " << answer <<
" inside of P2" << std::endl;
446 else if (INTER ==
false && MS ==
false && check_all ==
true && p2 ==
false && c2 ==
false) {
448 A->checkTopologyAndGeometry();
463 boost::shared_ptr<PolyhedralCone_Rn>,
469 DD(C, lexmin_ite, truncationStep);
472 cout <<
"TIME=" << this_timer.elapsed() << std::endl;
474 if (C->numberOfGenerators()==0 && C->numberOfHalfSpaces()==0)
475 cout <<
"The result is empty." << std::endl;
477 if (generatorsToCheck != 0) {
478 if (generatorsToCheck == C->numberOfGenerators())
479 cout <<
"Found " << generatorsToCheck <<
" generators..... OK" << std::endl;
481 cout <<
"Found " << C->numberOfGenerators() <<
" generators instead of " << generatorsToCheck <<
" KO !!!!!" << std::endl;
483 if (facetsToCheck != 0) {
484 if (facetsToCheck == C->numberOfHalfSpaces())
485 cout <<
"Found " << facetsToCheck <<
" facets ..... OK" << std::endl;
487 cout <<
"Found " << C->numberOfHalfSpaces() <<
" facets instead of " << facetsToCheck <<
" KO !!!!!" << std::endl;
489 std::string FileOut(
"output");
490 FileOut += fileName1;
492 FileOut = outputFileName;
496 if (BOUNDS ==
true) {
497 if (C->numberOfGenerators() != 0) {
498 std::vector< double > allMin;
499 std::vector< double > allMax;
500 for (
unsigned int i=0; i<dimension; ++i) {
502 allMin.push_back(std::numeric_limits<double>::max());
503 allMax.push_back(std::numeric_limits<double>::min());
507 {
for (iteGN1.
begin(); iteGN1.
end()!=
true; iteGN1.
next()) {
508 for (
unsigned int i=0; i<dimension; ++i) {
510 if (iteGN1.
current()->getCoordinate(i) < allMin[i])
511 allMin[i] = iteGN1.
current()->getCoordinate(i);
512 if (iteGN1.
current()->getCoordinate(i) > allMax[i])
513 allMax[i] = iteGN1.
current()->getCoordinate(i);
516 std::vector< double > diff;
517 for (
unsigned int i=0; i<dimension; ++i)
518 diff.push_back(allMax[i] - allMin[i]);
519 std::cout << std::endl <<
"Minima: ";
520 for (
unsigned int i=0; i<dimension; ++i)
521 std::cout << allMin[i] <<
" ";
522 std::cout << std::endl << std::endl <<
"Maxima: ";
523 for (
unsigned int i=0; i<dimension; ++i)
524 std::cout << allMax[i] <<
" ";
525 std::cout << std::endl << std::endl <<
"Range: ";
526 for (
unsigned int i=0; i<dimension; ++i)
527 std::cout << diff[i] <<
" ";
528 std::cout << std::endl;
532 catch(std::invalid_argument& excep) {
533 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
534 cerr <<
"Invalid argument exception " << excep.what() << std::endl;
537 catch(std::out_of_range& excep) {
538 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
539 cerr <<
"Out of range exception " << excep.what() << std::endl;
542 catch(std::ios_base::failure& excep) {
543 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
544 cerr <<
"In/out exception " << excep.what() << std::endl;
547 catch(std::domain_error& excep) {
548 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
549 cerr <<
"Domain error exception " << excep.what() << std::endl;
552 catch(std::logic_error& excep) {
553 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
554 cerr <<
"Logic error exception " << excep.what() << std::endl;
558 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
559 cerr <<
"Unexpected exception caught !" << std::endl;
563 if (check_all ==
true)
564 C->checkTopologyAndGeometry();
565 else if (CHCK_EQ ==
true) {
566 if ((p1==
true && p2==
true) || (c1==
true && c2==
true))
569 cerr <<
"ERROR 2 polytopes or polyhedral cones are needed to check equality." << std::endl;
573 else if (computeDistances ==
true) {
574 if (vertexToComputeDistances >= 0) {
575 C->checkGenerator(vertexToComputeDistances, std::cout);
577 else if (facetToComputeDistances >= 0) {
578 C->checkFacet(facetToComputeDistances, std::cout);