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