1 /*
2 * BuildPolytope.cpp
3 *
4 * Created on: June 15, 2010
5 * Author: bedutra
6 */
7 #include "BuildPolytope.h"
8 #include <cstring>
9 #include <iostream>
10 #include <cassert>
11 #include <ctime>
12 #include <unistd.h>
13 #include "latte_system.h"
14
15 using namespace std;
16
17
BuildPolytope()18 BuildPolytope::BuildPolytope():
19 ambientDim(0),
20 dim(0),
21 integerPoints(true),
22 createdPolymakeFile(false), createdPolymakeDualFile(false),
23 createdLatteVRepFile(false), createdLatteHRepFile(false),
24 createdLatteHRepDualFile(false), createdLatteVRepDualFile(false),
25 numAffineHull(0)
26 {
27 time_t rawtime;
28 struct tm * timeinfo;
29 time ( &rawtime );
30 timeinfo = localtime ( &rawtime );
31
32 stringstream ss;
33 ss << "buildpolytope_";
34 ss << timeinfo->tm_min << "_" << timeinfo->tm_hour << "_" << timeinfo->tm_mday << "_" << timeinfo->tm_year +1990;
35 fileBaseName = ss.str();
36 }
37
38 /**
39 * Takes a point and adds it to our point vector.
40 * @onePoint: one point to add. Assumes this does not have a leading 1.
41 * We will add [1 onePoint] to the point vector
42 */
addPoint(vector<mpq_class> onePoint)43 void BuildPolytope::addPoint(vector<mpq_class> onePoint)
44 {
45 onePoint.insert(onePoint.begin(), 1);
46 points.push_back(onePoint);
47 }//addPoint
48
49
50 /**
51 * Checks to see if this polytope is centered, and then
52 * centers it if not.
53 * The center command keeps important properties like vertices and facets, but some are
54 * lost like SIMPLE and SIMPLICIAL.
55 *
56 * The origional un-centered polytope is lost. Also, we do not automatically re-read vertex and facet information.
57 */
centerPolytope()58 void BuildPolytope::centerPolytope()
59 {
60 if ( isCentered() )
61 return;
62 //I do not know why, but in the terminal I can type center f.polymake f.polymake,
63 //but here, it does not like it when the output and input files are the same.
64 //Hence the ".temp" file that is made and renamed.
65 system_with_error_check(string("center ") + shell_quote(getPolymakeFile()) + ".temp " + shell_quote(getPolymakeFile()));
66 rename((string(getPolymakeFile()+".temp ")).c_str(), getPolymakeFile().c_str());
67 points.clear();
68 facets.clear();
69 dualFacets.clear();
70 dualVertices.clear();
71 }
72
clearPoints()73 void BuildPolytope::clearPoints()
74 {
75 points.clear();
76 }
77
78 /**
79 * Deletes the generated file if it has been created.
80 */
deletePolymakeFile()81 void BuildPolytope::deletePolymakeFile() { if (createdPolymakeFile) unlink(getPolymakeFile().c_str());}
deletePolymakeDualFile()82 void BuildPolytope::deletePolymakeDualFile() { if ( createdPolymakeDualFile) unlink(getPolymakeDualFile().c_str());}
deleteLatteVRepFile()83 void BuildPolytope::deleteLatteVRepFile(){ if (createdLatteVRepFile) unlink(getLatteVRepFile().c_str());}
deleteLatteVRepDualFile()84 void BuildPolytope::deleteLatteVRepDualFile(){ if (createdLatteVRepDualFile) unlink(getLatteVRepDualFile().c_str());}
deleteLatteHRepFile()85 void BuildPolytope::deleteLatteHRepFile(){ if (createdLatteHRepFile) unlink(getLatteHRepFile().c_str());}
deleteLatteHRepDualFile()86 void BuildPolytope::deleteLatteHRepDualFile(){ if (createdLatteHRepDualFile) unlink(getLatteHRepDualFile().c_str());}
87 /**
88 * Builds the polymake file containing the points information.
89 * filename: fileBaseName.polymake.
90 */
buildPolymakeFile()91 void BuildPolytope::buildPolymakeFile()
92 {
93 ofstream file;
94
95 if ( createdPolymakeFile == true)
96 return; //already make polymake file!
97
98 createdPolymakeFile = true;
99
100 file.open(getPolymakeFile().c_str());
101 file << "POINTS" << endl;
102
103
104 for (int k = 0; k < (int)points.size(); ++k)
105 {
106 for (int vectorElm = 0; vectorElm < ambientDim+1; ++vectorElm)
107 {
108 file << points[k][vectorElm] << ' ';
109 }//vectorElm
110 file << endl;
111 }//for k
112
113 file.close();
114 }//buildPolymakeFile
115
116
117 /**
118 * Finds the dual vertices and prints them to a new polymake file.
119 * If this polytope is not centered, will center it.
120 */
buildPolymakeDualFile()121 void BuildPolytope::buildPolymakeDualFile()
122 {
123
124 if (createdPolymakeDualFile == true)
125 return;
126
127 findVerticesDual();//make sure we already know the dual vertices.
128 fstream file;
129 file.open(getPolymakeDualFile().c_str(), ios::out);
130 file << "VERTICES" << endl;
131 for(int i = 0; i < (int) dualVertices.size(); ++i)
132 {
133 for(size_t k = 0; k < dualVertices[i].size(); ++k)
134 file << dualVertices[i][k] << " ";
135 file << endl;
136 }//for i.
137
138 createdPolymakeDualFile = true;
139 file.close();
140 }
141
142 /**
143 * Prints a file containing the equations of the polytope for Latte.
144 * Includes affine hull linearity information if needed.
145 * filename: fileBaseName.hrep.latte.
146 */
buildLatteHRepFile()147 void BuildPolytope::buildLatteHRepFile()
148 {
149 if ( createdLatteHRepFile == true)
150 return; //already did this.
151
152 createdLatteHRepFile = true;
153 findFacets(); //facets information is saved in facets.
154 makeIntegerRows(facets);
155
156 //now print to a latte file.
157 ofstream file;
158
159 file.open(getLatteHRepFile().c_str());
160
161 file << facets.size() << " " << ambientDim + 1 << endl;
162 for (int i = 0; i < (int) facets.size(); ++i)
163 {
164 for (int k = 0; k < ambientDim + 1; ++k)
165 file << facets[i][k] << " ";
166 file << endl;
167 }//for i
168
169 if (numAffineHull > 0)
170 {
171 file << "linearity " << numAffineHull << " ";
172 for (int i = (int)facets.size() - numAffineHull; i < (int)facets.size(); ++i)
173 {
174 file << i + 1 << " ";
175 }//for the affine hull equations.
176 file << endl;
177 }//if there are affine hulls!
178 file.close();}
179
180 /**
181 * Makes a latte dual h-rep file.
182 */
buildLatteHRepDualFile()183 void BuildPolytope::buildLatteHRepDualFile()
184 {
185 centerPolytope();
186 findFacetsDual();
187
188 if ( createdLatteHRepDualFile == true)
189 return; //already did this.
190
191 createdLatteHRepDualFile = true;
192 findFacetsDual(); //facets information is saved in facets.
193 makeIntegerRows(dualFacets);
194
195 //now print to a latte file.
196 ofstream file;
197
198 file.open(getLatteHRepDualFile().c_str());
199
200
201 file << dualFacets.size() << " " << ambientDim + 1 << endl;
202 for (int i = 0; i < (int) dualFacets.size(); ++i)
203 {
204 for (int k = 0; k < ambientDim + 1; ++k)
205 file << dualFacets[i][k] << " ";
206 file << endl;
207 }//for i
208
209 file.close();
210 }//buildLatteHRepDualFile
211
212 /**
213 * Prints a file containing the vertices of the polytope for Latte.
214 * filename: fileBaseName.vrep.latte.
215 */
buildLatteVRepFile()216 void BuildPolytope::buildLatteVRepFile()
217 {
218 if ( createdLatteVRepFile == true)
219 return; //already did this.
220
221 createdLatteVRepFile = true;
222 findVertices(); //facets information is saved in facets.
223 makeIntegerList(points);
224
225 //now print to a latte file.
226 ofstream file;
227
228 file.open(getLatteVRepFile().c_str());
229
230 file << points.size() << " " << ambientDim + 1 << endl;
231 for (int i = 0; i < (int) points.size(); ++i)
232 {
233 for (int k = 0; k < ambientDim + 1; ++k)
234 file << points[i][k] << " ";
235 file << endl;
236 }//for i
237
238 file << endl;
239 file.close();
240 }
241
242 /**
243 * Makes a latte dual v-rep from the facets information.
244 */
buildLatteVRepDualFile()245 void BuildPolytope::buildLatteVRepDualFile()
246 {
247 if ( createdLatteVRepDualFile == true)
248 return; //already did this.
249
250 createdLatteVRepDualFile = true;
251 findVerticesDual();
252 makeIntegerList(dualVertices);//after this, dualVertices are in the form [a, vij], vij are integer
253
254 //now print to a latte file.
255 ofstream file;
256
257 file.open(getLatteVRepDualFile().c_str());
258
259
260 file << dualVertices.size() << " " << ambientDim + 1 << endl;
261 for (int i = 0; i < (int) dualVertices.size(); ++i)
262 {
263 file << dualVertices[i][0] << " ";
264 for (int k = 1; k < ambientDim + 1; ++k)
265 file << dualVertices[i][k] << " ";
266 file << endl;
267 }//for i
268
269 file << endl;
270 file.close();
271 }//buildLatteVRepFualFIle()
272
273 /*
274 * Assumes the polymake file exist and polymake has already ran.
275 */
findDimentions()276 void BuildPolytope::findDimentions()
277 {
278 if ( dim > 0)
279 return; //already found it, don't waste time.
280
281 ifstream file;
282 string line;
283 file.open(getPolymakeFile().c_str());
284 for (getline(file, line, '\n'); line != "DIM"; getline(file, line, '\n'))
285 ;
286 file >> dim;
287 file.close();
288
289 file.open(getPolymakeFile().c_str());
290 for (getline(file, line, '\n'); line != "AMBIENT_DIM"; getline(file, line, '\n'))
291 ;
292 file >> ambientDim;
293 file.close();
294
295 assert(0 < dim && dim <= ambientDim);
296 }
297
298 /**
299 * Reads the polymake facet information into the facet vector.
300 * Builds the polymake file if needed.
301 * @rationalize: default is true. If true, each facet equation is mult. by a different positive number s.t. each slot is integer.
302 */
findFacets()303 void BuildPolytope::findFacets()
304 {
305 buildPolymakeFile();
306
307 //ask polymake for the
308
309 system_with_error_check((string("polymake ") + shell_quote(getPolymakeFile()) + " DIM AMBIENT_DIM FACETS AFFINE_HULL > /dev/null ").c_str());
310
311 //next, read the polymake file.
312
313 findDimentions();
314 ifstream file;
315 string line;
316 file.open(getPolymakeFile().c_str());
317 for (getline(file, line, '\n'); line != "FACETS"; getline(file, line, '\n'))
318 ;
319
320 facets.clear();
321
322 getline(file, line, '\n');
323 string term;
324 while (line != "")
325 {
326 stringstream ss(line);
327 vector<mpq_class> oneFacet;
328
329 for (int k = 0; k < ambientDim + 1; ++k)
330 {
331 ss >> term;
332 oneFacet.push_back(mpq_class(term));
333 }//for k
334 facets.push_back(oneFacet);//hyperplane has rational coeffs.
335 getline(file, line, '\n');
336 }//while
337 /*
338 *
339 string term;
340 file >> term;
341 do
342 {
343 vector<mpq_class> oneFacet;
344 for (int i = 0; i < ambientDim + 1; ++i)
345 {
346 oneFacet.push_back(mpq_class(term));
347 file >> term;
348 //cout << term << ". " ;
349 }//for i
350
351 facets.push_back(oneFacet);
352 } while (! file.eof() && isStringNumber(term)); // != "AFFINE_HULL");
353
354 */
355 file.close();
356 findAffineHull(); //we need to close and reopen the file to find this because we do not know which one (facets or affineHull) comes first, and I'm not worried about the time cost of doing this.
357
358
359 }//findFacets
360
361
362 /**
363 * Assumes facets and amb. dim has already been found and read in.
364 * inserts the equations at the end of the facets vector.
365 */
366
findAffineHull()367 void BuildPolytope::findAffineHull()
368 {
369 ifstream file;
370 string line;
371 string term;
372 file.open(getPolymakeFile().c_str());
373 for (getline(file, line, '\n'); line != "AFFINE_HULL"; getline(file, line, '\n'))
374 ;
375
376 getline(file, line, '\n');
377 numAffineHull = 0;
378 while (line != "")
379 {
380 stringstream ss(line);
381 vector<mpq_class> oneFacet;
382
383 for (int k = 0; k < ambientDim + 1; ++k)
384 {
385 ss >> term;
386 oneFacet.push_back(mpq_class(term));
387 }//for k
388 facets.push_back(oneFacet);
389 numAffineHull += 1;
390 getline(file, line, '\n');
391 }//while
392 file.close();
393 }//findAffineHull
394
findFacetsDual()395 void BuildPolytope::findFacetsDual()
396 {
397 centerPolytope();
398 dualFacets = getVertices();
399 }//findFacetsDual()
400
401
402
403
404
405 /**
406 * Reads the polymake vertex information into the points vector.
407 * Builds the polymake file if needed.
408 */
findVertices()409 void BuildPolytope::findVertices()
410 {
411 buildPolymakeFile();
412
413 //ask polymake for the
414 system_with_error_check((string("polymake ") + shell_quote(getPolymakeFile()) + " DIM AMBIENT_DIM VERTICES > /dev/null ").c_str());
415
416
417 //next, read the polymake file.
418 findDimentions();
419 ifstream file;
420 string line;
421 file.open(getPolymakeFile().c_str());
422
423 for (getline(file, line, '\n'); line != "VERTICES"; getline(file, line, '\n'))
424 ;
425
426 points.clear(); //remove old points information.
427
428 getline(file, line, '\n');
429 string term;
430 while (line != "")
431 {
432 stringstream ss(line);
433 vector<mpq_class> oneRay;
434
435 for (int k = 0; k < ambientDim + 1; ++k)
436 {
437 ss >> term;
438 oneRay.push_back(mpq_class(term));
439 }//for k
440 points.push_back(oneRay);//points are rational.
441 getline(file, line, '\n');
442 }//while
443 file.close();
444 }
445
446 /**
447 * finds the dual vertices.
448 * After this call, dualVertices have the form [1, vi], vi are rational.
449 */
findVerticesDual()450 void BuildPolytope::findVerticesDual()
451 {
452 if ( dualVertices.size() > 0)
453 return;
454
455 centerPolytope();
456 assert( getDim() == getAmbientDim() ); //duals are only defined for full dim.
457
458 findFacets();
459
460 dualVertices = getFacets();
461
462 homogenizeDualVertices(); //after this, dualVertices are in the form [1, vij], vij are rational
463 }
464
465
466 //int BuildPolytope::gcd(int a, int b) const;
getAmbientDim() const467 int BuildPolytope::getAmbientDim() const {return ambientDim;}
getDim() const468 int BuildPolytope::getDim() const {return dim;}
469
getFacets() const470 vector<vector<mpq_class> > BuildPolytope::getFacets() const {return facets;}
471
472
getLatteVRepFile() const473 string BuildPolytope::getLatteVRepFile() const {return fileBaseName + ".vrep.latte";}
getLatteVRepDualFile() const474 string BuildPolytope::getLatteVRepDualFile() const {return fileBaseName + ".vrep.dual.latte";}
getLatteHRepFile() const475 string BuildPolytope::getLatteHRepFile() const { return fileBaseName + ".hrep.latte";}
getLatteHRepDualFile() const476 string BuildPolytope::getLatteHRepDualFile() const { return fileBaseName + ".hrep.dual.latte";}
getPolymakeFile() const477 string BuildPolytope::getPolymakeFile() const { return fileBaseName + ".polymake";}
getPolymakeDualFile() const478 string BuildPolytope::getPolymakeDualFile() const { return getDualFileBaseName() +".polymake";}
getDualFileBaseName() const479 string BuildPolytope::getDualFileBaseName() const { return fileBaseName + ".dual";} //private function.
480
481
482 /**
483 * Returns the homogenize vertices
484 */
getVertices()485 vector<vector<mpq_class> > BuildPolytope::getVertices()
486 {
487 findVertices();
488 return points;
489 }//getVertices
490
getVertexCount()491 int BuildPolytope::getVertexCount()
492 {
493 findVertices();
494 return points.size();
495 }
496
getVertexDualCount()497 int BuildPolytope::getVertexDualCount()
498 {
499 findVerticesDual();
500 return dualVertices.size();
501 }
502
503 /**
504 * Right now the dualVertices are in the form [b v1 ... vn], after this call
505 * they will be in form [1, v1/b, ..., vn/b].
506 */
homogenizeDualVertices()507 void BuildPolytope::homogenizeDualVertices()
508 {
509 for(size_t i = 0; i < dualVertices.size(); ++i)
510 {
511 assert(dualVertices[i][0] > 0);
512
513 for(size_t j = 1; j < dualVertices[i].size(); ++j)
514 dualVertices[i][j] /= dualVertices[i][0];
515 dualVertices[i][0] = 1;
516 }//for i;
517 }//homogenizeDualVertices
518
isCentered()519 bool BuildPolytope::isCentered()
520 {
521 buildPolymakeFile();
522
523 //ask polymake
524 system_with_error_check((string("polymake ") + shell_quote(getPolymakeFile()) + " CENTERED > /dev/null ").c_str());
525
526 //next, read the polymake file.
527 ifstream file;
528 string line;
529 file.open(getPolymakeFile().c_str());
530
531 for (getline(file, line, '\n'); line != "CENTERED"; getline(file, line, '\n'))
532 ;
533
534 char ans;
535 ans = file.get();
536 file.close();
537
538 return (ans == '1');
539 }//isCentered
540
541
542 /**
543 * true if s is a number in for form 4, 4.5, or 4/5
544
545 bool BuildPolytope::isStringNumber(const string & s) const
546 {
547 bool signCount =0, decimalCount=0, rationalCount=0;
548
549 if ( s.length() == 0)
550 return false;
551
552 for(int i = 0; i < s.length(); ++i)
553 {
554 if ( isdigit(s[i]))
555 continue;
556
557 if ( s[i] == '-')
558 {
559 if (signCount)
560 return false; //too many signs
561 else
562 signCount++;
563 }
564 else if (s[i] == '.')
565 {
566 if (decimalCount)
567 return false; //too many decimal points
568 else
569 decimalCount++;
570 }
571 else if ( s[i] == '/')
572 {
573 if (rationalCount)
574 return false; //too many /
575 else
576 rationalCount++;
577 }
578 else
579 return false;
580
581 }//for i
582 return true;
583 }//isStringNumber
584 */
585
isSimplicial()586 bool BuildPolytope::isSimplicial()
587 {
588 buildPolymakeFile();
589
590 //ask polymake
591 system_with_error_check(string("polymake ") + shell_quote(getPolymakeFile()) + " SIMPLICIAL > /dev/null ");
592
593
594 //next, read the polymake file.
595 ifstream file;
596 string line;
597 file.open(getPolymakeFile().c_str());
598
599 for (getline(file, line, '\n'); line != "SIMPLICIAL"; getline(file, line, '\n'))
600 ;
601
602 char ans;
603 ans = file.get();
604 file.close();
605
606 return (ans == '1');
607 }
608
isSimple()609 bool BuildPolytope::isSimple()
610 {
611 buildPolymakeFile();
612
613 //ask polymake
614 system_with_error_check(string("polymake ") + shell_quote(getPolymakeFile()) + " DIM > /dev/null ");
615 system_with_error_check(string("polymake ") + shell_quote(getPolymakeFile()) + " SIMPLE > /dev/null ");
616
617
618 //next, read the polymake file.
619 ifstream file;
620 string line;
621 file.open(getPolymakeFile().c_str());
622
623 for (getline(file, line, '\n'); line != "SIMPLE"; getline(file, line, '\n'))
624 ;
625
626 char ans;
627 ans = file.get();
628 file.close();
629
630 return (ans == '1');
631 }
632
633
634 /**
635 * If a polytope is simplicial, then its dual is simple.
636 */
isDualSimplicial()637 bool BuildPolytope::isDualSimplicial()
638 {
639 return ! isSimple();
640 }//isDualSimplicial().
641
642 /**
643 * If a polytope is simple, then its dual is simplicial.
644 */
isDualSimple()645 bool BuildPolytope::isDualSimple()
646 {
647 return ! isSimplicial();
648 }//isDualSimplicial().
649
650
651 /**
652 * @list: a vector of facets or vertices. Will mult each row by a different number to clear each denominators for latte
653 *
654 */
makeIntegerRows(vector<vector<mpq_class>> & list)655 void BuildPolytope::makeIntegerRows(vector<vector<mpq_class> > &list)
656 {
657
658 for (int i = 0; i < (int) list.size(); ++i)
659 {
660 mpz_class currentLCM(1); //sorry, I was having a hard time calling with mpz_class
661 //it seems to only work with mpz_t, hence these two variables. (currentLCM and currentlcm)
662
663
664 //find the lcm of al the denominator for this row only.
665 for (int k = 0; k < ambientDim + 1; ++k)
666 {
667 mpz_t currentlcm; //set the output variable to 1.
668 mpz_init_set_si(currentlcm, 1);
669
670 if ( list[i][k] == mpz_class(0))
671 continue;
672
673 mpz_lcm(currentlcm, currentLCM.get_mpz_t(), list[i][k].get_den_mpz_t());
674 currentLCM = mpz_class(currentlcm);//save the current lcm in the c++ object.
675 }//for k
676
677 assert(currentLCM > 0);
678
679 //mult each element in this row by the lcm.
680 if (currentLCM != mpz_class(1))
681 {
682 for (int k = 0; k < ambientDim + 1; ++k)
683 {
684 list[i][k] = list[i][k] * currentLCM;
685 assert(list[i][k].get_den() == mpz_class(1));
686 }//for k
687 }//divide by the gcd
688 }//for i
689
690 //check everything looks ok.
691 //for(int i = 0; i < (int) facets.size(); ++i)
692 //{
693 // cout << "reduced facet " << i << " = ";
694 // for(int k = 0; k < ambientDim+1; ++k)
695 // cout << facets[i][k] << ", ";
696 // cout << endl;
697 //}//for i
698
699 }//makeIntegerRows();
700
701 /**
702 * @list: a vector of facets or vertices. Will mult each row by the same number to clear each denominators for latte
703 *
704 */
makeIntegerList(vector<vector<mpq_class>> & list)705 void BuildPolytope::makeIntegerList(vector<vector<mpq_class> > &list)
706 {
707 mpz_t currentLCM;
708 mpz_init_set_si(currentLCM, 1);
709
710 //currentLCM = 1
711 //loop over everything and find the lcm of the denom.
712 for (int i = 0; i < (int) list.size(); ++i)
713 {
714 for (int k = 0; k < (int) list[i].size(); ++k)
715 {
716 if (list[i][k] != mpq_class(0))
717 {
718 mpz_lcm(currentLCM, currentLCM,
719 list[i][k].get_den_mpz_t());
720 }//if not zero.
721 }//for k
722 }//for i
723
724 //cout << "makeIntegerList::" << endl;
725 //debugPrintList(list);
726 //cout << "makeIntegerList:: the lcm is " << mpz_class(currentLCM) << endl;
727
728 mpz_class currentLCM_mpz_class(currentLCM);
729 assert(currentLCM_mpz_class > 0);
730
731 //loop over everything again and times by the lcm.
732 for (size_t i = 0; i < list.size(); ++i)
733 {
734 for (size_t k = 0; k < list[i].size(); ++k)
735 {
736 list[i][k] = list[i][k] * currentLCM_mpz_class;
737 }//for k
738 }//for i
739 }//makeIntegerList
740
741
setBaseFileName(const string & n)742 void BuildPolytope::setBaseFileName(const string & n) {fileBaseName = n;}
743
744 /**
745 * Children of this class can use this method when building polytopes.
746 */
setIntegerPoints(bool t)747 void BuildPolytope::setIntegerPoints(bool t) { integerPoints = t; }
setBuildPolymakeFile(bool t)748 void BuildPolytope::setBuildPolymakeFile(bool t) { createdPolymakeFile = t;}
setBuildLatteVRepDualFile(bool t)749 void BuildPolytope::setBuildLatteVRepDualFile(bool t) { createdLatteVRepDualFile = t;}
750
751 /**
752 * This method makes a random polytope.
753 */
forDebugging()754 void BuildPolytope::forDebugging()
755 {
756 ambientDim = 3;
757 srand(time(NULL));
758
759 for (int i = 0; i < ambientDim+1+5; ++i)
760 {
761 vector<mpq_class> onePoint;
762 onePoint.push_back(1);
763 for(int j = 0; j < ambientDim; ++j)
764 if ( integerPoints )
765 onePoint.push_back(mpq_class(rand()%100,1));
766 else
767 onePoint.push_back(mpq_class(rand()%100, rand()%25));
768 points.push_back(onePoint);
769 }
770 }
771
772 /**
773 * Prints a facet, vertex, dual facet, or dual vertex list.
774 */
debugPrintList(const vector<vector<mpq_class>> & list)775 void BuildPolytope::debugPrintList(const vector<vector<mpq_class> > &list)
776 {
777 for(int i = 0; i < (int) list.size(); ++i)
778 {
779 cout << "i " << i << "= ";
780 for(int j = 0; j < (int) list[i].size(); ++j)
781 cout << list[i][j] << " ";
782 cout << endl;
783 }//for i
784 }//debugPrintList
785
786
787
788
789