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;
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) {
154 else if (strcmp(argv[i],
"-IN") == 0 || strcmp(argv[i],
"--Intersection") == 0) {
160 else if (strcmp(argv[i],
"-SS") == 0 || strcmp(argv[i],
"--Subset") == 0) {
167 else if (strcmp(argv[i],
"-EQ") == 0 || strcmp(argv[i],
"--Equality") == 0) {
173 else if (strcmp(argv[i],
"-bb") == 0 || strcmp(argv[i],
"--boundingbox") == 0) {
175 cerr <<
"Invalid bounding box dimension " << argv[i] << std::endl;
180 boundingVolume =
true;
181 boundingSize = atof(argv[++i]);
183 else if (strcmp(argv[i],
"-bs") == 0 || strcmp(argv[i],
"--boundingsimplex") == 0) {
185 cerr <<
"Invalid bounding simplex dimension " << argv[i] << std::endl;
191 boundingVolume =
true;
192 boundingSize = atof(argv[++i]);
194 else if (strcmp(argv[i],
"-d") == 0 || strcmp(argv[i],
"--dimension") == 0) {
196 cerr <<
"Invalid cartesian space dimension " << argv[i] << std::endl;
199 dimension = atoi(argv[++i]);
202 else if (strcmp(argv[i],
"-t") == 0 || strcmp(argv[i],
"--tolerance") == 0) {
204 cerr <<
"Invalid cartesian space tolerance " << argv[i] << std::endl;
207 tolerance = atof(argv[++i]);
210 else if (strcmp(argv[i],
"-VO") == 0 || strcmp(argv[i],
"--Volume") == 0) {
214 else if (strcmp(argv[i],
"-cg") == 0 || strcmp(argv[i],
"--check-generators") == 0) {
216 cerr <<
"Invalid number of generators to check " << argv[i] << std::endl;
219 generatorsToCheck = atoi(argv[++i]);
220 RunOptions::setCheckGeneratorsTest(
true);
221 RunOptions::setCheckGeneratorsValue(generatorsToCheck);
223 else if (strcmp(argv[i],
"-cf") == 0 || strcmp(argv[i],
"--check-facets") == 0) {
225 cerr <<
"Invalid number of facets to check " << argv[i] << std::endl;
228 facetsToCheck = atoi(argv[++i]);
229 RunOptions::setCheckGeneratorsTest(
true);
230 RunOptions::setCheckGeneratorsValue(generatorsToCheck);
232 else if (strcmp(argv[i],
"--generator") == 0) {
234 cerr <<
"Invalid number of generator " << argv[i] << std::endl;
237 vertexToComputeDistances = atoi(argv[++i]);
238 computeDistances =
true;
243 else if (strcmp(argv[i],
"--facet") == 0) {
245 cerr <<
"Invalid number of facet " << argv[i] << std::endl;
248 facetToComputeDistances = atoi(argv[++i]);
249 computeDistances =
true;
254 else if (strcmp(argv[i],
"-h") == 0 || strcmp(argv[i],
"--help") == 0) {
255 cout << version << std::endl;
256 cout <<
"\t-d [--dimension] ARG\t:\tSet the cartesian space dimension" << std::endl;
257 cout <<
"\t-t [--tolerance] ARG\t:\tSet the cartesian space tolerance [default: 1.e-06]" << std::endl;
258 cout <<
"\t-o [--output] ARG\t:\tThe optional output file (ptop or pcon extension)" << std::endl;
259 cout <<
"\t-p1 [--polytope1] ARG\t:\tFirst polytope input file (ptop extension)" << std::endl;
260 cout <<
"\t-p2 [--polytope2] ARG\t:\tSecond polytope input file (ptop extension)" << std::endl;
261 cout <<
"\t-c1 [--polyhedralcone1] ARG\t:\tFirst polyhedral cone input file (pcon extension)" << std::endl;
262 cout <<
"\t-c2 [--polyhedralcone2] ARG\t:\tSecond polyhedral cone input file (pcon extension)" << std::endl;
263 cout <<
"\t-cf [--check-facets] ARG\t:\tUsed to test when we know the final number of facets" << std::endl;
264 cout <<
"\t-cg [--check-generators] ARG\t:\tUsed to test when we know the final number of generators" << std::endl;
265 cout <<
"\t-bs [--boundingsimplex] ARG\t:\tBounding simplex size, containing the bounding box -bb (n+1 vertices)" << std::endl;
266 cout <<
"\t-bb [--boundingbox] ARG\t:\tBounding box size centered on the origin including the polytope (2^n vertices)" << std::endl;
267 cout <<
"\t-ch [--check-all]\t\t:\tUsed to perform all tests (no arguments, can be slow)." << std::endl;
268 cout <<
"\t-MS [--MinkowskiSum] \t:\tSet the option to turn on Minkowski sums" << std::endl;
269 cout <<
"\t-IN [--Intersection] \t:\tSet the option to turn on intersections (default option)" << std::endl;
270 cout <<
"\t-SS [--Subset] \t:\tSet the option to test whether P1 is included in P2" << std::endl;
271 cout <<
"\t-VO [--Volume] \t:\tSet the option to turn on the volume computation for the polytope" << std::endl;
272 cout <<
"\t-EQ [--Equality] \t:\tSet the option to turn on the equality check between ptop or pcon" << std::endl;
273 cout <<
"\t-v [--version]\t\t\t:\tGive the current version" << std::endl;
277 cerr <<
"Unknown option " << argv[i] << std::endl;
283 cerr <<
"Dimension has not been set." << std::endl;
289 if (c2 ==
true || p2 ==
true)
290 if (MS ==
false && CHCK_EQ ==
false && SUBSET ==
false)
293 int truncationStep = 0;
294 boost::shared_ptr<PolyhedralCone_Rn> A;
295 boost::shared_ptr<PolyhedralCone_Rn> B;
296 boost::shared_ptr<PolyhedralCone_Rn> C;
302 if (boundingVolume ==
true) {
303 if (A->numberOfGenerators() == 0) {
305 if (boundingBox ==
true) {
307 A->createBoundingBox(boundingSize);
311 A->createBoundingSimplex(boundingSize);
315 boost::shared_ptr<Polytope_Rn> PA = boost::static_pointer_cast<
Polytope_Rn>(A);
317 if (check_all ==
true)
318 PA->checkTopologyAndGeometry();
319 std::string FileOut(
"output");
320 FileOut += fileName1;
322 FileOut = outputFileName;
342 catch(std::ios_base::failure& e) {
343 cerr <<
"In/out exception: " << e.what() << std::endl;
347 if ((p1==
true && p2==
true) || (c1==
true && c2==
true)) {
348 if (p1==
true && p2==
true) {
354 {
for (
unsigned int i=0; i<A->numberOfGenerators(); i++) {
355 C->addGenerator(A->getGenerator(i));
358 for (iteHSA.begin(); iteHSA.end()!=
true; iteHSA.next()) {
359 C->addHalfSpace(iteHSA.current());
362 for (iteHSB.begin(); iteHSB.end()!=
true; iteHSB.next()) {
363 C->addHalfSpace(iteHSB.current());
365 truncationStep = A->numberOfHalfSpaces();
367 else if ((p1==
true && p2!=
true) || (c1==
true && c2!=
true)) {
372 cerr <<
"This program needs at least one polytope or one polyhedral cone and no mix between them." << std::endl;
376 boost::timer this_timer;
379 if ((MS ==
true) || (INTER ==
true) || (COMPUTE_VOL ==
true) || (SUBSET ==
true)) {
382 if (p1!=
true || p2!=
true) {
383 cout <<
"ERROR 2 polytopes are needed to compute the minkowski sum." << std::endl;
397 boost::shared_ptr<Polytope_Rn> PA = boost::static_pointer_cast<
Polytope_Rn>(A);
398 boost::shared_ptr<Polytope_Rn> PB = boost::static_pointer_cast<
Polytope_Rn>(B);
399 boost::shared_ptr<Polytope_Rn> PC = boost::static_pointer_cast<
Polytope_Rn>(C);
403 else if (COMPUTE_VOL ==
true) {
404 boost::shared_ptr<Polytope_Rn> Pol = boost::static_pointer_cast<
Polytope_Rn>(C);
406 cout <<
"VolumeOfPolytope=" << volumeOfPolytope << std::endl;
409 else if (SUBSET ==
true) {
410 bool isInside = A->isIncluded(B);
411 std::string answer = (isInside ==
true) ?
"" :
"not";
412 cout <<
"P1 is " << answer <<
" inside of P2" << std::endl;
415 else if (INTER ==
false && MS ==
false && check_all ==
true && p2 ==
false && c2 ==
false) {
417 A->checkTopologyAndGeometry();
432 boost::shared_ptr<PolyhedralCone_Rn>,
438 DD(C, lexmin_ite, NRP, truncationStep);
441 cout <<
"TIME=" << this_timer.elapsed() << std::endl;
443 if (C->numberOfGenerators()==0 && C->numberOfHalfSpaces()==0)
444 cout <<
"The result is empty." << std::endl;
446 if (generatorsToCheck != 0) {
447 if (generatorsToCheck == C->numberOfGenerators())
448 cout <<
"Found " << generatorsToCheck <<
" generators..... OK" << std::endl;
450 cout <<
"Found " << C->numberOfGenerators() <<
" generators instead of " << generatorsToCheck <<
" KO !!!!!" << std::endl;
452 if (facetsToCheck != 0) {
453 if (facetsToCheck == C->numberOfHalfSpaces())
454 cout <<
"Found " << facetsToCheck <<
" facets ..... OK" << std::endl;
456 cout <<
"Found " << C->numberOfHalfSpaces() <<
" facets instead of " << facetsToCheck <<
" KO !!!!!" << std::endl;
458 std::string FileOut(
"output");
459 FileOut += fileName1;
461 FileOut = outputFileName;
466 catch(std::invalid_argument& excep) {
467 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
468 cerr <<
"Invalid argument exception " << excep.what() << std::endl;
471 catch(std::out_of_range& excep) {
472 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
473 cerr <<
"Out of range exception " << excep.what() << std::endl;
476 catch(std::ios_base::failure& excep) {
477 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
478 cerr <<
"In/out exception " << excep.what() << std::endl;
481 catch(std::domain_error& excep) {
482 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
483 cerr <<
"Domain error exception " << excep.what() << std::endl;
486 catch(std::logic_error& excep) {
487 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
488 cerr <<
"Logic error exception " << excep.what() << std::endl;
492 cerr <<
"TIME=" << this_timer.elapsed() << std::endl;
493 cerr <<
"Unexpected exception caught !" << std::endl;
497 if (check_all ==
true)
498 C->checkTopologyAndGeometry();
499 else if (CHCK_EQ ==
true) {
500 if ((p1==
true && p2==
true) || (c1==
true && c2==
true))
503 cerr <<
"ERROR 2 polytopes or polyhedral cones are needed to check equality." << std::endl;
507 else if (computeDistances ==
true) {
508 if (vertexToComputeDistances >= 0) {
509 C->checkGenerator(vertexToComputeDistances, std::cout);
511 else if (facetToComputeDistances >= 0) {
512 C->checkFacet(facetToComputeDistances, std::cout);
static polito_EXPORT void setDimension(unsigned int dim)
Set the dimension for the cartesian space we work in.
#define politopix_VERSION_MINOR
#define politopix_VERSION_MAJOR
Model a polytope using its two equivalent definitions : the convex hull and the half-space intersecti...
Model a polyhedral cone using its two equivalent definitions : the convex hull and the half-space int...
Compute the Minkowski sum of two polytopes.
static polito_EXPORT void load(const std::string &filename, boost::shared_ptr< PolyhedralCone_Rn > POLY)
Load the main data format to store polytopes.
static polito_EXPORT void save(const std::string &filename, boost::shared_ptr< PolyhedralCone_Rn > POLY)
Save the polytope to the main data format.
static polito_EXPORT void setTolerance(double t)
Give the minimum distance between two points.
static polito_EXPORT double getTolerance()
Give the minimum distance between two points.
static polito_EXPORT unsigned int getDimension()
Return the dimension of the cartesian space we work in.
static double compute(const boost::shared_ptr< Polytope_Rn > P)
Return the volume of the given polytope P.
This class can be more time-consuming than WeakRedundancyProcessing or NoRedundancyProcessing because...
This class is designed to run the list of all geometric objects representing a polytope.
#define politopix_VERSION_PATCH
static int Compute(boost::shared_ptr< Polytope_Rn > &pol, double bb_size=1000.)
Use the polarity to get the facets from the generators.
int main(int argc, char *argv[])
The algorithm implemented here is an incremental algorithm as mentioned in How Good are Convex Hull ...