blob: 783dd1c3f60a17d1756b8ff0e1bb5db551b8de18 [file] [log] [blame]
Austin Schuh405fa6c2015-09-06 18:13:55 -07001/* cddio.c: Basic Input and Output Procedures for cddlib
2 written by Komei Fukuda, fukuda@math.ethz.ch
3 Version 0.94h, April 30, 2015
4*/
5
6/* cddlib : C-library of the double description method for
7 computing all vertices and extreme rays of the polyhedron
8 P= {x : b - A x >= 0}.
9 Please read COPYING (GNU General Public Licence) and
10 the manual cddlibman.tex for detail.
11*/
12
13#include "setoper.h" /* set operation library header (Ver. June 1, 2000 or later) */
14#include "cdd.h"
15#include <stdio.h>
16#include <stdlib.h>
17#include <time.h>
18#include <math.h>
19#include <string.h>
20
21/* void dd_fread_rational_value (FILE *, mytype *); */
22void dd_SetLinearity(dd_MatrixPtr, char *);
23
24void dd_SetInputFile(FILE **f,dd_DataFileType inputfile,dd_ErrorType *Error)
25{
26 int opened=0,stop,quit=0;
27 int i,dotpos=0,trial=0;
28 char ch;
29 char *tempname;
30
31
32 *Error=dd_NoError;
33 while (!opened && !quit) {
34 fprintf(stderr,"\n>> Input file: ");
35 scanf("%s",inputfile);
36 ch=getchar();
37 stop=dd_FALSE;
38 for (i=0; i<dd_filenamelen && !stop; i++){
39 ch=inputfile[i];
40 switch (ch) {
41 case '.':
42 dotpos=i+1;
43 break;
44 case ';': case ' ': case '\0': case '\n': case '\t':
45 stop=dd_TRUE;
46 tempname=(char*)calloc(dd_filenamelen,sizeof(ch));
47 strncpy(tempname,inputfile,i);
48 strcpy(inputfile,tempname);
49 free(tempname);
50 break;
51 }
52 }
53 if ( ( *f = fopen(inputfile,"r") )!= NULL) {
54 fprintf(stderr,"input file %s is open\n",inputfile);
55 opened=1;
56 *Error=dd_NoError;
57 }
58 else{
59 fprintf(stderr,"The file %s not found\n",inputfile);
60 trial++;
61 if (trial>5) {
62 *Error=dd_IFileNotFound;
63 quit=1;
64 }
65 }
66 }
67}
68
69void dd_SetWriteFileName(dd_DataFileType inputfile, dd_DataFileType outfile, char cflag, dd_RepresentationType rep)
70{
Brian Silvermanf1cff392015-10-11 19:36:18 -040071 const char *extension;
Austin Schuh405fa6c2015-09-06 18:13:55 -070072 dd_DataFileType ifilehead="";
73 int i,dotpos;
74
75 switch (cflag) {
76 case 'o':
77 switch (rep) {
78 case dd_Generator:
79 extension=".ine"; break; /* output file for ine data */
80 case dd_Inequality:
81 extension=".ext"; break; /* output file for ext data */
82 default:
83 extension=".xxx";break;
84 }
85 break;
86
87 case 'a': /* decide for output adjacence */
88 if (rep==dd_Inequality)
89 extension=".ead"; /* adjacency file for ext data */
90 else
91 extension=".iad"; /* adjacency file for ine data */
92 break;
93 case 'i': /* decide for output incidence */
94 if (rep==dd_Inequality)
95 extension=".ecd"; /* ext incidence file */
96 else
97 extension=".icd"; /* ine incidence file */
98 break;
99 case 'n': /* decide for input incidence */
100 if (rep==dd_Inequality)
101 extension=".icd"; /* ine incidence file */
102 else
103 extension=".ecd"; /* ext incidence file */
104 break;
105 case 'j': /* decide for input adjacency */
106 if (rep==dd_Inequality)
107 extension=".iad"; /* ine adjacency file */
108 else
109 extension=".ead"; /* ext adjacency file */
110 break;
111 case 'l':
112 extension=".ddl";break; /* log file */
113 case 'd':
114 extension=".dex";break; /* decomposition output */
115 case 'p':
116 extension="sub.ine";break; /* preprojection sub inequality file */
117 case 'v':
118 extension=".solved";break; /* verify_input file */
119 case 's':
120 extension=".lps";break; /* LP solution file */
121 default:
122 extension=".xxx";break;
123 }
124 dotpos=-1;
125 for (i=0; i< strlen(inputfile); i++){
126 if (inputfile[i]=='.') dotpos=i;
127 }
128 if (dotpos>1) strncpy(ifilehead, inputfile, dotpos);
129 else strcpy(ifilehead,inputfile);
130 if (strlen(inputfile)<=0) strcpy(ifilehead,"tempcdd");
131 strcpy(outfile,ifilehead);
132 strcat(outfile,extension);
133 if (strcmp(inputfile, outfile)==0) {
134 strcpy(outfile,inputfile);
135 strcat(outfile,extension);
136 }
137/* fprintf(stderr,"outfile name = %s\n",outfile); */
138}
139
140
141dd_NumberType dd_GetNumberType(const char *line)
142{
143 dd_NumberType nt;
144
145 if (strncmp(line, "integer", 7)==0) {
146 nt = dd_Integer;
147 }
148 else if (strncmp(line, "rational", 8)==0) {
149 nt = dd_Rational;
150 }
151 else if (strncmp(line, "real", 4)==0) {
152 nt = dd_Real;
153 }
154 else {
155 nt=dd_Unknown;
156 }
157 return nt;
158}
159
160void dd_ProcessCommandLine(FILE *f, dd_MatrixPtr M, const char *line)
161{
162 char newline[dd_linelenmax];
163 dd_colrange j;
164 mytype value;
165
166 dd_init(value);
167 if (strncmp(line, "hull", 4)==0) {
168 M->representation = dd_Generator;
169 }
170 if (strncmp(line, "debug", 5)==0) {
171 dd_debug = dd_TRUE;
172#ifdef GMPRATIONAL
173 ddf_debug = ddf_TRUE;
174#endif
175 }
176 if (strncmp(line, "partial_enum", 12)==0 ||
177 strncmp(line, "equality", 8)==0 ||
178 strncmp(line, "linearity", 9)==0 ) {
179 fgets(newline,dd_linelenmax,f);
180 dd_SetLinearity(M,newline);
181 }
182 if (strncmp(line, "maximize", 8)==0 ||
183 strncmp(line, "minimize", 8)==0) {
184 if (strncmp(line, "maximize", 8)==0) M->objective=dd_LPmax;
185 else M->objective=dd_LPmin;
186 for (j = 1; j <= M->colsize; j++) {
187 if (M->numbtype==dd_Real) {
188#if !defined(GMPRATIONAL)
189 double rvalue;
190 fscanf(f, "%lf", &rvalue);
191 dd_set_d(value, rvalue);
192#endif
193 } else {
194 dd_fread_rational_value (f, value);
195 }
196 dd_set(M->rowvec[j - 1],value);
197 if (dd_debug) {fprintf(stderr,"cost(%5ld) =",j); dd_WriteNumber(stderr,value);}
198 } /*of j*/
199 }
200 dd_clear(value);
201}
202
203dd_boolean dd_AppendMatrix2Poly(dd_PolyhedraPtr *poly, dd_MatrixPtr M)
204{
205 dd_boolean success=dd_FALSE;
206 dd_MatrixPtr Mpoly,Mnew=NULL;
207 dd_ErrorType err;
208
209 if ((*poly)!=NULL && (*poly)->m >=0 && (*poly)->d>=0 &&
210 (*poly)->d==M->colsize && M->rowsize>0){
211 Mpoly=dd_CopyInput(*poly);
212 Mnew=dd_AppendMatrix(Mpoly, M);
213 dd_FreePolyhedra(*poly);
214 *poly=dd_DDMatrix2Poly(Mnew,&err);
215 dd_FreeMatrix(Mpoly);
216 dd_FreeMatrix(Mnew);
217 if (err==dd_NoError) success=dd_TRUE;
218 }
219 return success;
220}
221
222dd_MatrixPtr dd_MatrixCopy(dd_MatrixPtr M)
223{
224 dd_MatrixPtr Mcopy=NULL;
225 dd_rowrange m;
226 dd_colrange d;
227
228 m= M->rowsize;
229 d= M->colsize;
230 if (m >=0 && d >=0){
231 Mcopy=dd_CreateMatrix(m, d);
232 dd_CopyAmatrix(Mcopy->matrix, M->matrix, m, d);
233 dd_CopyArow(Mcopy->rowvec, M->rowvec, d);
234 set_copy(Mcopy->linset,M->linset);
235 Mcopy->numbtype=M->numbtype;
236 Mcopy->representation=M->representation;
237 Mcopy->objective=M->objective;
238 }
239 return Mcopy;
240}
241
242dd_MatrixPtr dd_CopyMatrix(dd_MatrixPtr M)
243{
244 return dd_MatrixCopy(M);
245}
246
247dd_MatrixPtr dd_MatrixNormalizedCopy(dd_MatrixPtr M)
248{
249 dd_MatrixPtr Mcopy=NULL;
250 dd_rowrange m;
251 dd_colrange d;
252
253 m= M->rowsize;
254 d= M->colsize;
255 if (m >=0 && d >=0){
256 Mcopy=dd_CreateMatrix(m, d);
257 dd_CopyNormalizedAmatrix(Mcopy->matrix, M->matrix, m, d);
258 dd_CopyArow(Mcopy->rowvec, M->rowvec, d);
259 set_copy(Mcopy->linset,M->linset);
260 Mcopy->numbtype=M->numbtype;
261 Mcopy->representation=M->representation;
262 Mcopy->objective=M->objective;
263 }
264 return Mcopy;
265}
266
267
268dd_MatrixPtr dd_MatrixAppend(dd_MatrixPtr M1, dd_MatrixPtr M2)
269{
270 dd_MatrixPtr M=NULL;
271 dd_rowrange i, m,m1,m2;
272 dd_colrange j, d,d1,d2;
273
274 m1=M1->rowsize;
275 d1=M1->colsize;
276 m2=M2->rowsize;
277 d2=M2->colsize;
278
279 m=m1+m2;
280 d=d1;
281
282 if (d1>=0 && d1==d2 && m1>=0 && m2>=0){
283 M=dd_CreateMatrix(m, d);
284 dd_CopyAmatrix(M->matrix, M1->matrix, m1, d);
285 dd_CopyArow(M->rowvec, M1->rowvec, d);
286 for (i=0; i<m1; i++){
287 if (set_member(i+1,M1->linset)) set_addelem(M->linset,i+1);
288 }
289 for (i=0; i<m2; i++){
290 for (j=0; j<d; j++)
291 dd_set(M->matrix[m1+i][j],M2->matrix[i][j]);
292 /* append the second matrix */
293 if (set_member(i+1,M2->linset)) set_addelem(M->linset,m1+i+1);
294 }
295 M->numbtype=M1->numbtype;
296 }
297 return M;
298}
299
300dd_MatrixPtr dd_MatrixNormalizedSortedCopy(dd_MatrixPtr M,dd_rowindex *newpos) /* 094 */
301{
302 /* Sort the rows of Amatrix lexicographically, and return a link to this sorted copy.
303 The vector newpos is allocated, where newpos[i] returns the new row index
304 of the original row i (i=1,...,M->rowsize). */
305 dd_MatrixPtr Mcopy=NULL,Mnorm=NULL;
306 dd_rowrange m,i;
307 dd_colrange d;
308 dd_rowindex roworder;
309
310 /* if (newpos!=NULL) free(newpos); */
311 m= M->rowsize;
312 d= M->colsize;
313 roworder=(long *)calloc(m+1,sizeof(long));
314 *newpos=(long *)calloc(m+1,sizeof(long));
315 if (m >=0 && d >=0){
316 Mnorm=dd_MatrixNormalizedCopy(M);
317 Mcopy=dd_CreateMatrix(m, d);
318 for(i=1; i<=m; i++) roworder[i]=i;
319
320 dd_RandomPermutation(roworder, m, 123);
321 dd_QuickSort(roworder,1,m,Mnorm->matrix,d);
322
323 dd_PermuteCopyAmatrix(Mcopy->matrix, Mnorm->matrix, m, d, roworder);
324 dd_CopyArow(Mcopy->rowvec, M->rowvec, d);
325 for(i=1; i<=m; i++) {
326 if (set_member(roworder[i],M->linset)) set_addelem(Mcopy->linset, i);
327 (*newpos)[roworder[i]]=i;
328 }
329 Mcopy->numbtype=M->numbtype;
330 Mcopy->representation=M->representation;
331 Mcopy->objective=M->objective;
332 dd_FreeMatrix(Mnorm);
333 }
334 free(roworder);
335 return Mcopy;
336}
337
338dd_MatrixPtr dd_MatrixUniqueCopy(dd_MatrixPtr M,dd_rowindex *newpos)
339{
340 /* Remove row duplicates, and return a link to this sorted copy.
341 Linearity rows have priority over the other rows.
342 It is better to call this after sorting with dd_MatrixNormalizedSortedCopy.
343 The vector newpos is allocated, where *newpos[i] returns the new row index
344 of the original row i (i=1,...,M->rowsize). *newpos[i] is negative if the original
345 row is dominated by -*newpos[i] and eliminated in the new copy.
346 */
347 dd_MatrixPtr Mcopy=NULL;
348 dd_rowrange m,i,uniqrows;
349 dd_rowset preferredrows;
350 dd_colrange d;
351 dd_rowindex roworder;
352
353 /* if (newpos!=NULL) free(newpos); */
354 m= M->rowsize;
355 d= M->colsize;
356 preferredrows=M->linset;
357 roworder=(long *)calloc(m+1,sizeof(long));
358 if (m >=0 && d >=0){
359 for(i=1; i<=m; i++) roworder[i]=i;
360 dd_UniqueRows(roworder, 1, m, M->matrix, d,preferredrows, &uniqrows);
361
362 Mcopy=dd_CreateMatrix(uniqrows, d);
363 dd_PermutePartialCopyAmatrix(Mcopy->matrix, M->matrix, m, d, roworder,1,m);
364 dd_CopyArow(Mcopy->rowvec, M->rowvec, d);
365 for(i=1; i<=m; i++) {
366 if (roworder[i]>0 && set_member(i,M->linset)) set_addelem(Mcopy->linset, roworder[i]);
367 }
368 Mcopy->numbtype=M->numbtype;
369 Mcopy->representation=M->representation;
370 Mcopy->objective=M->objective;
371 }
372 *newpos=roworder;
373 return Mcopy;
374}
375
376
377dd_MatrixPtr dd_MatrixNormalizedSortedUniqueCopy(dd_MatrixPtr M,dd_rowindex *newpos) /* 094 */
378{
379 /* Sort and remove row duplicates, and return a link to this sorted copy.
380 Linearity rows have priority over the other rows.
381 It is better to call this after sorting with dd_MatrixNormalizedSortedCopy.
382 The vector newpos is allocated, where *newpos[i] returns the new row index
383 of the original row i (i=1,...,M->rowsize). *newpos[i] is negative if the original
384 row is dominated by -*newpos[i] and eliminated in the new copy.
385 */
386 dd_MatrixPtr M1=NULL,M2=NULL;
387 dd_rowrange m,i;
388 dd_colrange d;
389 dd_rowindex newpos1=NULL,newpos1r=NULL,newpos2=NULL;
390
391 /* if (newpos!=NULL) free(newpos); */
392 m= M->rowsize;
393 d= M->colsize;
394 *newpos=(long *)calloc(m+1,sizeof(long));
395 newpos1r=(long *)calloc(m+1,sizeof(long));
396 if (m>=0 && d>=0){
397 M1=dd_MatrixNormalizedSortedCopy(M,&newpos1);
398 for (i=1; i<=m;i++) newpos1r[newpos1[i]]=i; /* reverse of newpos1 */
399 M2=dd_MatrixUniqueCopy(M1,&newpos2);
400 set_emptyset(M2->linset);
401 for(i=1; i<=m; i++) {
402 if (newpos2[newpos1[i]]>0){
403 printf("newpos1[%ld]=%ld, newpos2[newpos1[%ld]]=%ld\n",i,newpos1[i], i,newpos2[newpos1[i]]);
404 if (set_member(i,M->linset)) set_addelem(M2->linset, newpos2[newpos1[i]]);
405 (*newpos)[i]=newpos2[newpos1[i]];
406 } else {
407 (*newpos)[i]=-newpos1r[-newpos2[newpos1[i]]];
408 }
409 }
410 dd_FreeMatrix(M1);free(newpos1);free(newpos2);free(newpos1r);
411 }
412
413 return M2;
414}
415
416dd_MatrixPtr dd_MatrixSortedUniqueCopy(dd_MatrixPtr M,dd_rowindex *newpos) /* 094 */
417{
418 /* Same as dd_MatrixNormalizedSortedUniqueCopy except that it returns a unnormalized origial data
419 with original ordering.
420 */
421 dd_MatrixPtr M1=NULL,M2=NULL;
422 dd_rowrange m,i,k,ii;
423 dd_colrange d;
424 dd_rowindex newpos1=NULL,newpos1r=NULL,newpos2=NULL;
425
426 /* if (newpos!=NULL) free(newpos); */
427 m= M->rowsize;
428 d= M->colsize;
429 *newpos=(long *)calloc(m+1,sizeof(long));
430 newpos1r=(long *)calloc(m+1,sizeof(long));
431 if (m>=0 && d>=0){
432 M1=dd_MatrixNormalizedSortedCopy(M,&newpos1);
433 for (i=1; i<=m;i++) newpos1r[newpos1[i]]=i; /* reverse of newpos1 */
434 M2=dd_MatrixUniqueCopy(M1,&newpos2);
435 dd_FreeMatrix(M1);
436 set_emptyset(M2->linset);
437 for(i=1; i<=m; i++) {
438 if (newpos2[newpos1[i]]>0){
439 if (set_member(i,M->linset)) set_addelem(M2->linset, newpos2[newpos1[i]]);
440 (*newpos)[i]=newpos2[newpos1[i]];
441 } else {
442 (*newpos)[i]=-newpos1r[-newpos2[newpos1[i]]];
443 }
444 }
445
446 ii=0;
447 set_emptyset(M2->linset);
448 for (i = 1; i<=m ; i++) {
449 k=(*newpos)[i];
450 if (k>0) {
451 ii+=1;
452 (*newpos)[i]=ii;
453 dd_CopyArow(M2->matrix[ii-1],M->matrix[i-1],d);
454 if (set_member(i,M->linset)) set_addelem(M2->linset, ii);
455 }
456 }
457
458 free(newpos1);free(newpos2);free(newpos1r);
459 }
460
461 return M2;
462}
463
464dd_MatrixPtr dd_AppendMatrix(dd_MatrixPtr M1, dd_MatrixPtr M2)
465{
466 return dd_MatrixAppend(M1,M2);
467}
468
469int dd_MatrixAppendTo(dd_MatrixPtr *M1, dd_MatrixPtr M2)
470{
471 dd_MatrixPtr M=NULL;
472 dd_rowrange i, m,m1,m2;
473 dd_colrange j, d,d1,d2;
474 dd_boolean success=0;
475
476 m1=(*M1)->rowsize;
477 d1=(*M1)->colsize;
478 m2=M2->rowsize;
479 d2=M2->colsize;
480
481 m=m1+m2;
482 d=d1;
483
484 if (d1>=0 && d1==d2 && m1>=0 && m2>=0){
485 M=dd_CreateMatrix(m, d);
486 dd_CopyAmatrix(M->matrix, (*M1)->matrix, m1, d);
487 dd_CopyArow(M->rowvec, (*M1)->rowvec, d);
488 for (i=0; i<m1; i++){
489 if (set_member(i+1,(*M1)->linset)) set_addelem(M->linset,i+1);
490 }
491 for (i=0; i<m2; i++){
492 for (j=0; j<d; j++)
493 dd_set(M->matrix[m1+i][j],M2->matrix[i][j]);
494 /* append the second matrix */
495 if (set_member(i+1,M2->linset)) set_addelem(M->linset,m1+i+1);
496 }
497 M->numbtype=(*M1)->numbtype;
498 dd_FreeMatrix(*M1);
499 *M1=M;
500 success=1;
501 }
502 return success;
503}
504
505int dd_MatrixRowRemove(dd_MatrixPtr *M, dd_rowrange r) /* 092 */
506{
507 dd_rowrange i,m;
508 dd_colrange d;
509 dd_boolean success=0;
510
511 m=(*M)->rowsize;
512 d=(*M)->colsize;
513
514 if (r >= 1 && r <=m){
515 (*M)->rowsize=m-1;
516 dd_FreeArow(d, (*M)->matrix[r-1]);
517 set_delelem((*M)->linset,r);
518 /* slide the row headers */
519 for (i=r; i<m; i++){
520 (*M)->matrix[i-1]=(*M)->matrix[i];
521 if (set_member(i+1, (*M)->linset)){
522 set_delelem((*M)->linset,i+1);
523 set_addelem((*M)->linset,i);
524 }
525 }
526 success=1;
527 }
528 return success;
529}
530
531int dd_MatrixRowRemove2(dd_MatrixPtr *M, dd_rowrange r, dd_rowindex *newpos) /* 094 */
532{
533 dd_rowrange i,m;
534 dd_colrange d;
535 dd_boolean success=0;
536 dd_rowindex roworder;
537
538 m=(*M)->rowsize;
539 d=(*M)->colsize;
540
541 if (r >= 1 && r <=m){
542 roworder=(long *)calloc(m+1,sizeof(long));
543 (*M)->rowsize=m-1;
544 dd_FreeArow(d, (*M)->matrix[r-1]);
545 set_delelem((*M)->linset,r);
546 /* slide the row headers */
547 for (i=1; i<r; i++) roworder[i]=i;
548 roworder[r]=0; /* meaning it is removed */
549 for (i=r; i<m; i++){
550 (*M)->matrix[i-1]=(*M)->matrix[i];
551 roworder[i+1]=i;
552 if (set_member(i+1, (*M)->linset)){
553 set_delelem((*M)->linset,i+1);
554 set_addelem((*M)->linset,i);
555 }
556 }
557 success=1;
558 }
559 return success;
560}
561
562dd_MatrixPtr dd_MatrixSubmatrix(dd_MatrixPtr M, dd_rowset delset) /* 092 */
563{
564 dd_MatrixPtr Msub=NULL;
565 dd_rowrange i,isub=1, m,msub;
566 dd_colrange d;
567
568 m= M->rowsize;
569 d= M->colsize;
570 msub=m;
571 if (m >=0 && d >=0){
572 for (i=1; i<=m; i++) {
573 if (set_member(i,delset)) msub-=1;
574 }
575 Msub=dd_CreateMatrix(msub, d);
576 for (i=1; i<=m; i++){
577 if (!set_member(i,delset)){
578 dd_CopyArow(Msub->matrix[isub-1], M->matrix[i-1], d);
579 if (set_member(i, M->linset)){
580 set_addelem(Msub->linset,isub);
581 }
582 isub++;
583 }
584 }
585 dd_CopyArow(Msub->rowvec, M->rowvec, d);
586 Msub->numbtype=M->numbtype;
587 Msub->representation=M->representation;
588 Msub->objective=M->objective;
589 }
590 return Msub;
591}
592
593dd_MatrixPtr dd_MatrixSubmatrix2(dd_MatrixPtr M, dd_rowset delset,dd_rowindex *newpos) /* 092 */
594{ /* returns a pointer to a new matrix which is a submatrix of M with rows in delset
595 removed. *newpos[i] returns the position of the original row i in the new matrix.
596 It is -1 if and only if it is deleted.
597 */
598
599 dd_MatrixPtr Msub=NULL;
600 dd_rowrange i,isub=1, m,msub;
601 dd_colrange d;
602 dd_rowindex roworder;
603
604 m= M->rowsize;
605 d= M->colsize;
606 msub=m;
607 if (m >=0 && d >=0){
608 roworder=(long *)calloc(m+1,sizeof(long));
609 for (i=1; i<=m; i++) {
610 if (set_member(i,delset)) msub-=1;
611 }
612 Msub=dd_CreateMatrix(msub, d);
613 for (i=1; i<=m; i++){
614 if (set_member(i,delset)){
615 roworder[i]=0; /* zero means the row i is removed */
616 } else {
617 dd_CopyArow(Msub->matrix[isub-1], M->matrix[i-1], d);
618 if (set_member(i, M->linset)){
619 set_addelem(Msub->linset,isub);
620 }
621 roworder[i]=isub;
622 isub++;
623 }
624 }
625 *newpos=roworder;
626 dd_CopyArow(Msub->rowvec, M->rowvec, d);
627 Msub->numbtype=M->numbtype;
628 Msub->representation=M->representation;
629 Msub->objective=M->objective;
630 }
631 return Msub;
632}
633
634
635dd_MatrixPtr dd_MatrixSubmatrix2L(dd_MatrixPtr M, dd_rowset delset,dd_rowindex *newpos) /* 094 */
636{ /* This is same as dd_MatrixSubmatrix2 except that the linearity rows will be shifted up
637 so that they are at the top of the matrix.
638 */
639 dd_MatrixPtr Msub=NULL;
640 dd_rowrange i,iL, iI, m,msub;
641 dd_colrange d;
642 dd_rowindex roworder;
643
644 m= M->rowsize;
645 d= M->colsize;
646 msub=m;
647 if (m >=0 && d >=0){
648 roworder=(long *)calloc(m+1,sizeof(long));
649 for (i=1; i<=m; i++) {
650 if (set_member(i,delset)) msub-=1;
651 }
652 Msub=dd_CreateMatrix(msub, d);
653 iL=1; iI=set_card(M->linset)+1; /* starting positions */
654 for (i=1; i<=m; i++){
655 if (set_member(i,delset)){
656 roworder[i]=0; /* zero means the row i is removed */
657 } else {
658 if (set_member(i,M->linset)){
659 dd_CopyArow(Msub->matrix[iL-1], M->matrix[i-1], d);
660 set_delelem(Msub->linset,i);
661 set_addelem(Msub->linset,iL);
662 roworder[i]=iL;
663 iL+=1;
664 } else {
665 dd_CopyArow(Msub->matrix[iI-1], M->matrix[i-1], d);
666 roworder[i]=iI;
667 iI+=1;
668 }
669 }
670 }
671 *newpos=roworder;
672 dd_CopyArow(Msub->rowvec, M->rowvec, d);
673 Msub->numbtype=M->numbtype;
674 Msub->representation=M->representation;
675 Msub->objective=M->objective;
676 }
677 return Msub;
678}
679
680int dd_MatrixRowsRemove(dd_MatrixPtr *M, dd_rowset delset) /* 094 */
681{
682 dd_MatrixPtr Msub=NULL;
683 int success;
684
685 Msub=dd_MatrixSubmatrix(*M, delset);
686 dd_FreeMatrix(*M);
687 *M=Msub;
688 success=1;
689 return success;
690}
691
692int dd_MatrixRowsRemove2(dd_MatrixPtr *M, dd_rowset delset,dd_rowindex *newpos) /* 094 */
693{
694 dd_MatrixPtr Msub=NULL;
695 int success;
696
697 Msub=dd_MatrixSubmatrix2(*M, delset,newpos);
698 dd_FreeMatrix(*M);
699 *M=Msub;
700 success=1;
701 return success;
702}
703
704int dd_MatrixShiftupLinearity(dd_MatrixPtr *M,dd_rowindex *newpos) /* 094 */
705{
706 dd_MatrixPtr Msub=NULL;
707 int success;
708 dd_rowset delset;
709
710 set_initialize(&delset,(*M)->rowsize); /* emptyset */
711 Msub=dd_MatrixSubmatrix2L(*M, delset,newpos);
712 dd_FreeMatrix(*M);
713 *M=Msub;
714
715 set_free(delset);
716 success=1;
717 return success;
718}
719
720dd_PolyhedraPtr dd_CreatePolyhedraData(dd_rowrange m, dd_colrange d)
721{
722 dd_rowrange i;
723 dd_PolyhedraPtr poly=NULL;
724
725 poly=(dd_PolyhedraPtr) malloc (sizeof(dd_PolyhedraType));
726 poly->child =NULL; /* this links the homogenized cone data */
727 poly->m =m;
728 poly->d =d;
729 poly->n =-1; /* the size of output is not known */
730 poly->m_alloc =m+2; /* the allocated row size of matrix A */
731 poly->d_alloc =d; /* the allocated col size of matrix A */
732 poly->ldim =0; /* initialize the linearity dimension */
733 poly->numbtype=dd_Real;
734 dd_InitializeAmatrix(poly->m_alloc,poly->d_alloc,&(poly->A));
735 dd_InitializeArow(d,&(poly->c)); /* cost vector */
736 poly->representation =dd_Inequality;
737 poly->homogeneous =dd_FALSE;
738
739 poly->EqualityIndex=(int *)calloc(m+2, sizeof(int));
740 /* size increased to m+2 in 092b because it is used by the child cone,
741 This is a bug fix suggested by Thao Dang. */
742 /* ith component is 1 if it is equality, -1 if it is strict inequality, 0 otherwise. */
743 for (i = 0; i <= m+1; i++) poly->EqualityIndex[i]=0;
744
745 poly->IsEmpty = -1; /* initially set to -1, neither TRUE nor FALSE, meaning unknown */
746
747 poly->NondegAssumed = dd_FALSE;
748 poly->InitBasisAtBottom = dd_FALSE;
749 poly->RestrictedEnumeration = dd_FALSE;
750 poly->RelaxedEnumeration = dd_FALSE;
751
752 poly->AincGenerated=dd_FALSE; /* Ainc is a set array to store the input incidence. */
753
754 return poly;
755}
756
757dd_boolean dd_InitializeConeData(dd_rowrange m, dd_colrange d, dd_ConePtr *cone)
758{
759 dd_boolean success=dd_TRUE;
760 dd_colrange j;
761
762 (*cone)=(dd_ConePtr)calloc(1, sizeof(dd_ConeType));
763
764/* INPUT: A given representation of a cone: inequality */
765 (*cone)->m=m;
766 (*cone)->d=d;
767 (*cone)->m_alloc=m+2; /* allocated row size of matrix A */
768 (*cone)->d_alloc=d; /* allocated col size of matrix A, B and Bsave */
769 (*cone)->numbtype=dd_Real;
770 (*cone)->parent=NULL;
771
772/* CONTROL: variables to control computation */
773 (*cone)->Iteration=0;
774
775 (*cone)->HalfspaceOrder=dd_LexMin;
776
777 (*cone)->ArtificialRay=NULL;
778 (*cone)->FirstRay=NULL;
779 (*cone)->LastRay=NULL; /* The second description: Generator */
780 (*cone)->PosHead=NULL;
781 (*cone)->ZeroHead=NULL;
782 (*cone)->NegHead=NULL;
783 (*cone)->PosLast=NULL;
784 (*cone)->ZeroLast=NULL;
785 (*cone)->NegLast=NULL;
786 (*cone)->RecomputeRowOrder = dd_TRUE;
787 (*cone)->PreOrderedRun = dd_FALSE;
788 set_initialize(&((*cone)->GroundSet),(*cone)->m_alloc);
789 set_initialize(&((*cone)->EqualitySet),(*cone)->m_alloc);
790 set_initialize(&((*cone)->NonequalitySet),(*cone)->m_alloc);
791 set_initialize(&((*cone)->AddedHalfspaces),(*cone)->m_alloc);
792 set_initialize(&((*cone)->WeaklyAddedHalfspaces),(*cone)->m_alloc);
793 set_initialize(&((*cone)->InitialHalfspaces),(*cone)->m_alloc);
794 (*cone)->RayCount=0;
795 (*cone)->FeasibleRayCount=0;
796 (*cone)->WeaklyFeasibleRayCount=0;
797 (*cone)->TotalRayCount=0;
798 (*cone)->ZeroRayCount=0;
799 (*cone)->EdgeCount=0;
800 (*cone)->TotalEdgeCount=0;
801 (*cone)->count_int=0;
802 (*cone)->count_int_good=0;
803 (*cone)->count_int_bad=0;
804 (*cone)->rseed=1; /* random seed for random row permutation */
805
806 dd_InitializeBmatrix((*cone)->d_alloc, &((*cone)->B));
807 dd_InitializeBmatrix((*cone)->d_alloc, &((*cone)->Bsave));
808 dd_InitializeAmatrix((*cone)->m_alloc,(*cone)->d_alloc,&((*cone)->A));
809
810 (*cone)->Edges
811 =(dd_AdjacencyType**) calloc((*cone)->m_alloc,sizeof(dd_AdjacencyType*));
812 for (j=0; j<(*cone)->m_alloc; j++) (*cone)->Edges[j]=NULL; /* 094h */
813 (*cone)->InitialRayIndex=(long*)calloc(d+1,sizeof(long));
814 (*cone)->OrderVector=(long*)calloc((*cone)->m_alloc+1,sizeof(long));
815
816 (*cone)->newcol=(long*)calloc(((*cone)->d)+1,sizeof(long));
817 for (j=0; j<=(*cone)->d; j++) (*cone)->newcol[j]=j; /* identity map, initially */
818 (*cone)->LinearityDim = -2; /* -2 if it is not computed */
819 (*cone)->ColReduced = dd_FALSE;
820 (*cone)->d_orig = d;
821
822/* STATES: variables to represent current state. */
823/*(*cone)->Error;
824 (*cone)->CompStatus;
825 (*cone)->starttime;
826 (*cone)->endtime;
827*/
828
829 return success;
830}
831
832dd_ConePtr dd_ConeDataLoad(dd_PolyhedraPtr poly)
833{
834 dd_ConePtr cone=NULL;
835 dd_colrange d,j;
836 dd_rowrange m,i;
837
838 m=poly->m;
839 d=poly->d;
840 if (!(poly->homogeneous) && poly->representation==dd_Inequality){
841 m=poly->m+1;
842 }
843 poly->m1=m;
844
845 dd_InitializeConeData(m, d, &cone);
846 cone->representation=poly->representation;
847
848/* Points to the original polyhedra data, and reversely */
849 cone->parent=poly;
850 poly->child=cone;
851
852 for (i=1; i<=poly->m; i++)
853 for (j=1; j<=cone->d; j++)
854 dd_set(cone->A[i-1][j-1],poly->A[i-1][j-1]);
855
856 if (poly->representation==dd_Inequality && !(poly->homogeneous)){
857 dd_set(cone->A[m-1][0],dd_one);
858 for (j=2; j<=d; j++) dd_set(cone->A[m-1][j-1],dd_purezero);
859 }
860
861 return cone;
862}
863
864void dd_SetLinearity(dd_MatrixPtr M, char *line)
865{
866 int i=0;
867 dd_rowrange eqsize,var;
868 char *next;
869 const char ct[]=", "; /* allows separators "," and " ". */
870
871 next=strtok(line,ct);
872 eqsize=atol(next);
873 while (i < eqsize && (next=strtok(NULL,ct))!=NULL) {
874 var=atol(next);
875 set_addelem(M->linset,var); i++;
876 }
877 if (i!=eqsize) {
878 fprintf(stderr,"* Warning: there are inconsistencies in linearity setting.\n");
879 }
880 return;
881}
882
883dd_MatrixPtr dd_PolyFile2Matrix (FILE *f, dd_ErrorType *Error)
884{
885 dd_MatrixPtr M=NULL;
886 dd_rowrange m_input,i;
887 dd_colrange d_input,j;
888 dd_RepresentationType rep=dd_Inequality;
889 mytype value;
890 dd_boolean found=dd_FALSE, newformat=dd_FALSE, successful=dd_FALSE, linearity=dd_FALSE;
891 char command[dd_linelenmax], comsave[dd_linelenmax], numbtype[dd_wordlenmax];
892 dd_NumberType NT;
893#if !defined(GMPRATIONAL)
894 double rvalue;
895#endif
896
897 dd_init(value);
898 (*Error)=dd_NoError;
899 while (!found)
900 {
901 if (fscanf(f,"%s",command)==EOF) {
902 (*Error)=dd_ImproperInputFormat;
903 goto _L99;
904 }
905 else {
906 if (strncmp(command, "V-representation", 16)==0) {
907 rep=dd_Generator; newformat=dd_TRUE;
908 }
909 if (strncmp(command, "H-representation", 16)==0){
910 rep=dd_Inequality; newformat=dd_TRUE;
911 }
912 if (strncmp(command, "partial_enum", 12)==0 ||
913 strncmp(command, "equality", 8)==0 ||
914 strncmp(command, "linearity", 9)==0 ) {
915 linearity=dd_TRUE;
916 fgets(comsave,dd_linelenmax,f);
917 }
918 if (strncmp(command, "begin", 5)==0) found=dd_TRUE;
919 }
920 }
921 fscanf(f, "%ld %ld %s", &m_input, &d_input, numbtype);
922 fprintf(stderr,"size = %ld x %ld\nNumber Type = %s\n", m_input, d_input, numbtype);
923 NT=dd_GetNumberType(numbtype);
924 if (NT==dd_Unknown) {
925 (*Error)=dd_ImproperInputFormat;
926 goto _L99;
927 }
928 M=dd_CreateMatrix(m_input, d_input);
929 M->representation=rep;
930 M->numbtype=NT;
931
932 for (i = 1; i <= m_input; i++) {
933 for (j = 1; j <= d_input; j++) {
934 if (NT==dd_Real) {
935#if defined GMPRATIONAL
936 *Error=dd_NoRealNumberSupport;
937 goto _L99;
938#else
939 fscanf(f, "%lf", &rvalue);
940 dd_set_d(value, rvalue);
941#endif
942 } else {
943 dd_fread_rational_value (f, value);
944 }
945 dd_set(M->matrix[i-1][j - 1],value);
946 if (dd_debug) {fprintf(stderr,"a(%3ld,%5ld) = ",i,j); dd_WriteNumber(stderr,value);}
947 } /*of j*/
948 } /*of i*/
949 if (fscanf(f,"%s",command)==EOF) {
950 (*Error)=dd_ImproperInputFormat;
951 goto _L99;
952 }
953 else if (strncmp(command, "end", 3)!=0) {
954 if (dd_debug) fprintf(stderr,"'end' missing or illegal extra data: %s\n",command);
955 (*Error)=dd_ImproperInputFormat;
956 goto _L99;
957 }
958
959 successful=dd_TRUE;
960 if (linearity) {
961 dd_SetLinearity(M,comsave);
962 }
963 while (!feof(f)) {
964 fscanf(f,"%s", command);
965 dd_ProcessCommandLine(f, M, command);
966 fgets(command,dd_linelenmax,f); /* skip the CR/LF */
967 }
968
969_L99: ;
970 dd_clear(value);
971 /* if (f!=NULL) fclose(f); */
972 return M;
973}
974
975
976dd_PolyhedraPtr dd_DDMatrix2Poly(dd_MatrixPtr M, dd_ErrorType *err)
977{
978 dd_rowrange i;
979 dd_colrange j;
980 dd_PolyhedraPtr poly=NULL;
981
982 *err=dd_NoError;
983 if (M->rowsize<0 || M->colsize<0){
984 *err=dd_NegativeMatrixSize;
985 goto _L99;
986 }
987 poly=dd_CreatePolyhedraData(M->rowsize, M->colsize);
988 poly->representation=M->representation;
989 poly->homogeneous=dd_TRUE;
990
991 for (i = 1; i <= M->rowsize; i++) {
992 if (set_member(i, M->linset)) {
993 poly->EqualityIndex[i]=1;
994 }
995 for (j = 1; j <= M->colsize; j++) {
996 dd_set(poly->A[i-1][j-1], M->matrix[i-1][j-1]);
997 if (j==1 && dd_Nonzero(M->matrix[i-1][j-1])) poly->homogeneous = dd_FALSE;
998 } /*of j*/
999 } /*of i*/
1000 dd_DoubleDescription(poly,err);
1001_L99:
1002 return poly;
1003}
1004
1005dd_PolyhedraPtr dd_DDMatrix2Poly2(dd_MatrixPtr M, dd_RowOrderType horder, dd_ErrorType *err)
1006{
1007 dd_rowrange i;
1008 dd_colrange j;
1009 dd_PolyhedraPtr poly=NULL;
1010
1011 *err=dd_NoError;
1012 if (M->rowsize<0 || M->colsize<0){
1013 *err=dd_NegativeMatrixSize;
1014 goto _L99;
1015 }
1016 poly=dd_CreatePolyhedraData(M->rowsize, M->colsize);
1017 poly->representation=M->representation;
1018 poly->homogeneous=dd_TRUE;
1019
1020 for (i = 1; i <= M->rowsize; i++) {
1021 if (set_member(i, M->linset)) {
1022 poly->EqualityIndex[i]=1;
1023 }
1024 for (j = 1; j <= M->colsize; j++) {
1025 dd_set(poly->A[i-1][j-1], M->matrix[i-1][j-1]);
1026 if (j==1 && dd_Nonzero(M->matrix[i-1][j-1])) poly->homogeneous = dd_FALSE;
1027 } /*of j*/
1028 } /*of i*/
1029 dd_DoubleDescription2(poly, horder, err);
1030_L99:
1031 return poly;
1032}
1033
1034void dd_MatrixIntegerFilter(dd_MatrixPtr M)
1035{ /* setting an almost integer to the integer. */
1036 dd_rowrange i;
1037 dd_colrange j;
1038 mytype x;
1039
1040 dd_init(x);
1041 for (i=0; i< M->rowsize; i++)
1042 for (j=0; j< M->colsize; j++){
1043 dd_SnapToInteger(x, M->matrix[i][j]);
1044 dd_set(M->matrix[i][j],x);
1045 }
1046 dd_clear(x);
1047}
1048
1049void dd_CopyRay(mytype *a, dd_colrange d_origsize, dd_RayPtr RR,
1050 dd_RepresentationType rep, dd_colindex reducedcol)
1051{
1052 long j,j1;
1053 mytype b;
1054
1055 dd_init(b);
1056 for (j = 1; j <= d_origsize; j++){
1057 j1=reducedcol[j];
1058 if (j1>0){
1059 dd_set(a[j-1],RR->Ray[j1-1]);
1060 /* the original column j is mapped to j1, and thus
1061 copy the corresponding component */
1062 } else {
1063 dd_set(a[j-1],dd_purezero);
1064 /* original column is redundant and removed for computation */
1065 }
1066 }
1067
1068 dd_set(b,a[0]);
1069 if (rep==dd_Generator && dd_Nonzero(b)){
1070 dd_set(a[0],dd_one);
1071 for (j = 2; j <= d_origsize; j++)
1072 dd_div(a[j-1],a[j-1],b); /* normalization for generators */
1073 }
1074 dd_clear(b);
1075}
1076
1077void dd_WriteRay(FILE *f, dd_colrange d_origsize, dd_RayPtr RR, dd_RepresentationType rep, dd_colindex reducedcol)
1078{
1079 dd_colrange j;
1080 static dd_colrange d_last=0;
1081 static dd_Arow a;
1082
1083 if (d_last< d_origsize){
1084 if (d_last>0) free(a);
1085 dd_InitializeArow(d_origsize+1, &a);
1086 d_last=d_origsize+1;
1087 }
1088
1089 dd_CopyRay(a, d_origsize, RR, rep, reducedcol);
1090 for (j = 0; j < d_origsize; j++) dd_WriteNumber(f, a[j]);
1091 fprintf(f, "\n");
1092}
1093
1094void dd_WriteArow(FILE *f, dd_Arow a, dd_colrange d)
1095{
1096 dd_colrange j;
1097
1098 for (j = 0; j < d; j++) dd_WriteNumber(f, a[j]);
1099 fprintf(f, "\n");
1100}
1101
1102void dd_WriteAmatrix(FILE *f, dd_Amatrix A, long rowmax, long colmax)
1103{
1104 long i,j;
1105
1106 if (A==NULL){
1107 fprintf(f, "WriteAmatrix: The requested matrix is empty\n");
1108 goto _L99;
1109 }
1110 fprintf(f, "begin\n");
1111#if defined GMPRATIONAL
1112 fprintf(f, " %ld %ld rational\n",rowmax, colmax);
1113#else
1114 fprintf(f, " %ld %ld real\n",rowmax, colmax);
1115#endif
1116 for (i=1; i <= rowmax; i++) {
1117 for (j=1; j <= colmax; j++) {
1118 dd_WriteNumber(f, A[i-1][j-1]);
1119 }
1120 fprintf(f,"\n");
1121 }
1122 fprintf(f, "end\n");
1123_L99:;
1124}
1125
1126void dd_WriteBmatrix(FILE *f, dd_colrange d_size, dd_Bmatrix B)
1127{
1128 dd_colrange j1, j2;
1129
1130 if (B==NULL){
1131 fprintf(f, "WriteBmatrix: The requested matrix is empty\n");
1132 goto _L99;
1133 }
1134 for (j1 = 0; j1 < d_size; j1++) {
1135 for (j2 = 0; j2 < d_size; j2++) {
1136 dd_WriteNumber(f, B[j1][j2]);
1137 } /*of j2*/
1138 putc('\n', f);
1139 } /*of j1*/
1140 putc('\n', f);
1141_L99:;
1142}
1143
1144void dd_WriteSetFamily(FILE *f, dd_SetFamilyPtr F)
1145{
1146 dd_bigrange i;
1147
1148 if (F==NULL){
1149 fprintf(f, "WriteSetFamily: The requested family is empty\n");
1150 goto _L99;
1151 }
1152 fprintf(f,"begin\n");
1153 fprintf(f," %ld %ld\n", F->famsize, F->setsize);
1154 for (i=0; i<F->famsize; i++) {
1155 fprintf(f, " %ld %ld : ", i+1, set_card(F->set[i]));
1156 set_fwrite(f, F->set[i]);
1157 }
1158 fprintf(f,"end\n");
1159_L99:;
1160}
1161
1162void dd_WriteSetFamilyCompressed(FILE *f, dd_SetFamilyPtr F)
1163{
1164 dd_bigrange i,card;
1165
1166 if (F==NULL){
1167 fprintf(f, "WriteSetFamily: The requested family is empty\n");
1168 goto _L99;
1169 }
1170 fprintf(f,"begin\n");
1171 fprintf(f," %ld %ld\n", F->famsize, F->setsize);
1172 for (i=0; i<F->famsize; i++) {
1173 card=set_card(F->set[i]);
1174 if (F->setsize - card >= card){
1175 fprintf(f, " %ld %ld : ", i+1, card);
1176 set_fwrite(f, F->set[i]);
1177 } else {
1178 fprintf(f, " %ld %ld : ", i+1, -card);
1179 set_fwrite_compl(f, F->set[i]);
1180 }
1181 }
1182 fprintf(f,"end\n");
1183_L99:;
1184}
1185
1186void dd_WriteMatrix(FILE *f, dd_MatrixPtr M)
1187{
1188 dd_rowrange i, linsize;
1189
1190 if (M==NULL){
1191 fprintf(f, "WriteMatrix: The requested matrix is empty\n");
1192 goto _L99;
1193 }
1194 switch (M->representation) {
1195 case dd_Inequality:
1196 fprintf(f, "H-representation\n"); break;
1197 case dd_Generator:
1198 fprintf(f, "V-representation\n"); break;
1199 case dd_Unspecified:
1200 break;
1201 }
1202 linsize=set_card(M->linset);
1203 if (linsize>0) {
1204 fprintf(f, "linearity %ld ", linsize);
1205 for (i=1; i<=M->rowsize; i++)
1206 if (set_member(i, M->linset)) fprintf(f, " %ld", i);
1207 fprintf(f, "\n");
1208 }
1209 dd_WriteAmatrix(f, M->matrix, M->rowsize, M->colsize);
1210 if (M->objective!=dd_LPnone){
1211 if (M->objective==dd_LPmax)
1212 fprintf(f, "maximize\n");
1213 else
1214 fprintf(f, "minimize\n");
1215 dd_WriteArow(f, M->rowvec, M->colsize);
1216 }
1217_L99:;
1218}
1219
1220void dd_WriteLP(FILE *f, dd_LPPtr lp)
1221{
1222 if (lp==NULL){
1223 fprintf(f, "WriteLP: The requested lp is empty\n");
1224 goto _L99;
1225 }
1226 fprintf(f, "H-representation\n");
1227
1228 dd_WriteAmatrix(f, lp->A, (lp->m)-1, lp->d);
1229 if (lp->objective!=dd_LPnone){
1230 if (lp->objective==dd_LPmax)
1231 fprintf(f, "maximize\n");
1232 else
1233 fprintf(f, "minimize\n");
1234 dd_WriteArow(f, lp->A[lp->objrow-1], lp->d);
1235 }
1236_L99:;
1237}
1238
1239
1240void dd_SnapToInteger(mytype y, mytype x)
1241{
1242 /* this is broken. It does nothing. */
1243 dd_set(y,x);
1244}
1245
1246
1247void dd_WriteReal(FILE *f, mytype x)
1248{
1249 long ix1,ix2,ix;
1250 double ax;
1251
1252 ax=dd_get_d(x);
1253 ix1= (long) (fabs(ax) * 10000. + 0.5);
1254 ix2= (long) (fabs(ax) + 0.5);
1255 ix2= ix2*10000;
1256 if ( ix1 == ix2) {
1257 if (dd_Positive(x)) {
1258 ix = (long)(ax + 0.5);
1259 } else {
1260 ix = (long)(-ax + 0.5);
1261 ix = -ix;
1262 }
1263 fprintf(f, " %2ld", ix);
1264 } else
1265 fprintf(f, " % .9E",ax);
1266}
1267
1268void dd_WriteNumber(FILE *f, mytype x)
1269{
1270#if defined GMPRATIONAL
1271 fprintf(f," ");
1272 mpq_out_str(f, 10, x);
1273#else
1274 dd_WriteReal(f, x);
1275#endif
1276}
1277
1278
1279void dd_WriteIncidence(FILE *f, dd_PolyhedraPtr poly)
1280{
1281 dd_SetFamilyPtr I;
1282
1283 switch (poly->representation) {
1284 case dd_Inequality:
1285 fprintf(f, "ecd_file: Incidence of generators and inequalities\n");
1286 break;
1287 case dd_Generator:
1288 fprintf(f, "icd_file: Incidence of inequalities and generators\n");
1289 break;
1290
1291 default:
1292 break;
1293 }
1294 I=dd_CopyIncidence(poly);
1295 dd_WriteSetFamilyCompressed(f,I);
1296 dd_FreeSetFamily(I);
1297}
1298
1299void dd_WriteAdjacency(FILE *f, dd_PolyhedraPtr poly)
1300{
1301 dd_SetFamilyPtr A;
1302
1303 switch (poly->representation) {
1304 case dd_Inequality:
1305 fprintf(f, "ead_file: Adjacency of generators\n");
1306 break;
1307 case dd_Generator:
1308 fprintf(f, "iad_file: Adjacency of inequalities\n");
1309 break;
1310
1311 default:
1312 break;
1313 }
1314 A=dd_CopyAdjacency(poly);
1315 dd_WriteSetFamilyCompressed(f,A);
1316 dd_FreeSetFamily(A);
1317}
1318
1319
1320void dd_ComputeAinc(dd_PolyhedraPtr poly)
1321{
1322/* This generates the input incidence array poly->Ainc, and
1323 two sets: poly->Ared, poly->Adom.
1324*/
1325 dd_bigrange k;
1326 dd_rowrange i,m1;
1327 dd_colrange j;
1328 dd_boolean redundant;
1329 dd_MatrixPtr M=NULL;
1330 mytype sum,temp;
1331
1332 dd_init(sum); dd_init(temp);
1333 if (poly->AincGenerated==dd_TRUE) goto _L99;
1334
1335 M=dd_CopyOutput(poly);
1336 poly->n=M->rowsize;
1337 m1=poly->m1;
1338 /* this number is same as poly->m, except when
1339 poly is given by nonhomogeneous inequalty:
1340 !(poly->homogeneous) && poly->representation==Inequality,
1341 it is poly->m+1. See dd_ConeDataLoad.
1342 */
1343 poly->Ainc=(set_type*)calloc(m1, sizeof(set_type));
1344 for(i=1; i<=m1; i++) set_initialize(&(poly->Ainc[i-1]),poly->n);
1345 set_initialize(&(poly->Ared), m1);
1346 set_initialize(&(poly->Adom), m1);
1347
1348 for (k=1; k<=poly->n; k++){
1349 for (i=1; i<=poly->m; i++){
1350 dd_set(sum,dd_purezero);
1351 for (j=1; j<=poly->d; j++){
1352 dd_mul(temp,poly->A[i-1][j-1],M->matrix[k-1][j-1]);
1353 dd_add(sum,sum,temp);
1354 }
1355 if (dd_EqualToZero(sum)) {
1356 set_addelem(poly->Ainc[i-1], k);
1357 }
1358 }
1359 if (!(poly->homogeneous) && poly->representation==dd_Inequality){
1360 if (dd_EqualToZero(M->matrix[k-1][0])) {
1361 set_addelem(poly->Ainc[m1-1], k); /* added infinity inequality (1,0,0,...,0) */
1362 }
1363 }
1364 }
1365
1366 for (i=1; i<=m1; i++){
1367 if (set_card(poly->Ainc[i-1])==M->rowsize){
1368 set_addelem(poly->Adom, i);
1369 }
1370 }
1371 for (i=m1; i>=1; i--){
1372 if (set_card(poly->Ainc[i-1])==0){
1373 redundant=dd_TRUE;
1374 set_addelem(poly->Ared, i);
1375 }else {
1376 redundant=dd_FALSE;
1377 for (k=1; k<=m1; k++) {
1378 if (k!=i && !set_member(k, poly->Ared) && !set_member(k, poly->Adom) &&
1379 set_subset(poly->Ainc[i-1], poly->Ainc[k-1])){
1380 if (!redundant){
1381 redundant=dd_TRUE;
1382 }
1383 set_addelem(poly->Ared, i);
1384 }
1385 }
1386 }
1387 }
1388 dd_FreeMatrix(M);
1389 poly->AincGenerated=dd_TRUE;
1390_L99:;
1391 dd_clear(sum); dd_clear(temp);
1392}
1393
1394dd_boolean dd_InputAdjacentQ(dd_PolyhedraPtr poly,
1395 dd_rowrange i1, dd_rowrange i2)
1396/* Before calling this function, RedundantSet must be
1397 a set of row indices whose removal results in a minimal
1398 nonredundant system to represent the input polyhedron,
1399 DominantSet must be the set of row indices which are
1400 active at every extreme points/rays.
1401*/
1402{
1403 dd_boolean adj=dd_TRUE;
1404 dd_rowrange i;
1405 static set_type common;
1406 static long lastn=0;
1407
1408 if (poly->AincGenerated==dd_FALSE) dd_ComputeAinc(poly);
1409 if (lastn!=poly->n){
1410 if (lastn >0) set_free(common);
1411 set_initialize(&common, poly->n);
1412 lastn=poly->n;
1413 }
1414 if (set_member(i1, poly->Ared) || set_member(i2, poly->Ared)){
1415 adj=dd_FALSE;
1416 goto _L99;
1417 }
1418 if (set_member(i1, poly->Adom) || set_member(i2, poly->Adom)){
1419 // dominant inequality is considered adjacencent to all others.
1420 adj=dd_TRUE;
1421 goto _L99;
1422 }
1423 set_int(common, poly->Ainc[i1-1], poly->Ainc[i2-1]);
1424 i=0;
1425 while (i<poly->m1 && adj==dd_TRUE){
1426 i++;
1427 if (i!=i1 && i!=i2 && !set_member(i, poly->Ared) &&
1428 !set_member(i, poly->Adom) && set_subset(common,poly->Ainc[i-1])){
1429 adj=dd_FALSE;
1430 }
1431 }
1432_L99:;
1433 return adj;
1434}
1435
1436
1437void dd_WriteInputIncidence(FILE *f, dd_PolyhedraPtr poly)
1438{
1439 dd_SetFamilyPtr I;
1440
1441 if (poly->AincGenerated==dd_FALSE) dd_ComputeAinc(poly);
1442 switch (poly->representation) {
1443 case dd_Inequality:
1444 fprintf(f,"icd_file: Incidence of inequalities and generators\n");
1445 break;
1446
1447 case dd_Generator:
1448 fprintf(f,"ecd_file: Incidence of generators and inequalities\n");
1449 break;
1450
1451 default:
1452 break;
1453 }
1454
1455 I=dd_CopyInputIncidence(poly);
1456 dd_WriteSetFamilyCompressed(f,I);
1457 dd_FreeSetFamily(I);
1458}
1459
1460void dd_WriteInputAdjacency(FILE *f, dd_PolyhedraPtr poly)
1461{
1462 dd_SetFamilyPtr A;
1463
1464 if (poly->AincGenerated==dd_FALSE){
1465 dd_ComputeAinc(poly);
1466 }
1467 switch (poly->representation) {
1468 case dd_Inequality:
1469 fprintf(f, "iad_file: Adjacency of inequalities\n");
1470 break;
1471
1472 case dd_Generator:
1473 fprintf(f, "ead_file: Adjacency of generators\n");
1474 break;
1475
1476 default:
1477 break;
1478 }
1479 A=dd_CopyInputAdjacency(poly);
1480 dd_WriteSetFamilyCompressed(f,A);
1481 dd_FreeSetFamily(A);
1482}
1483
1484
1485void dd_WriteProgramDescription(FILE *f)
1486{
1487 fprintf(f, "* cddlib: a double description library:%s\n", dd_DDVERSION);
1488 fprintf(f, "* compiled for %s arithmetic.\n", dd_ARITHMETIC);
1489 fprintf(f,"* %s\n",dd_COPYRIGHT);
1490}
1491
1492void dd_WriteTimes(FILE *f, time_t starttime, time_t endtime)
1493{
1494 long ptime,ptime_sec,ptime_minu, ptime_hour;
1495
1496/*
1497 ptime=difftime(endtime,starttime);
1498 This function is ANSI standard, but not available sometime
1499*/
1500 ptime=(endtime - starttime);
1501 /* This is to replace the line above, but it may not give
1502 correct time in seconds */
1503 ptime_hour=ptime/3600;
1504 ptime_minu=(ptime-ptime_hour*3600)/60;
1505 ptime_sec=ptime%60;
1506 fprintf(f,"* Computation started at %s",asctime(localtime(&starttime)));
1507 fprintf(f,"* ended at %s",asctime(localtime(&endtime)));
1508 fprintf(f,"* Total processor time = %ld seconds\n",ptime);
1509 fprintf(f,"* = %ld h %ld m %ld s\n",ptime_hour, ptime_minu, ptime_sec);
1510}
1511
1512void dd_WriteDDTimes(FILE *f, dd_PolyhedraPtr poly)
1513{
1514 dd_WriteTimes(f,poly->child->starttime,poly->child->endtime);
1515}
1516
1517void dd_WriteLPTimes(FILE *f, dd_LPPtr lp)
1518{
1519 dd_WriteTimes(f,lp->starttime,lp->endtime);
1520}
1521
1522void dd_WriteLPStats(FILE *f)
1523{
1524 time_t currenttime;
1525
1526 time(&currenttime);
1527
1528 fprintf(f, "\n*--- Statistics of pivots ---\n");
1529#if defined GMPRATIONAL
1530 fprintf(f, "* f0 = %ld (float basis finding pivots)\n",ddf_statBApivots);
1531 fprintf(f, "* fc = %ld (float CC pivots)\n",ddf_statCCpivots);
1532 fprintf(f, "* f1 = %ld (float dual simplex phase I pivots)\n",ddf_statDS1pivots);
1533 fprintf(f, "* f2 = %ld (float dual simplex phase II pivots)\n",ddf_statDS2pivots);
1534 fprintf(f, "* f3 = %ld (float anticycling CC pivots)\n",ddf_statACpivots);
1535 fprintf(f, "* e0 = %ld (exact basis finding pivots)\n",dd_statBApivots);
1536 fprintf(f, "* ec = %ld (exact CC pivots)\n",dd_statCCpivots);
1537 fprintf(f, "* e1 = %ld (exact dual simplex phase I pivots)\n",dd_statDS1pivots);
1538 fprintf(f, "* e2 = %ld (exact dual simplex phase II pivots)\n",dd_statDS2pivots);
1539 fprintf(f, "* e3 = %ld (exact anticycling CC pivots)\n",dd_statACpivots);
1540 fprintf(f, "* e4 = %ld (exact basis verification pivots)\n",dd_statBSpivots);
1541#else
1542 fprintf(f, "f0 = %ld (float basis finding pivots)\n",dd_statBApivots);
1543 fprintf(f, "fc = %ld (float CC pivots)\n",dd_statCCpivots);
1544 fprintf(f, "f1 = %ld (float dual simplex phase I pivots)\n",dd_statDS1pivots);
1545 fprintf(f, "f2 = %ld (float dual simplex phase II pivots)\n",dd_statDS2pivots);
1546 fprintf(f, "f3 = %ld (float anticycling CC pivots)\n",dd_statACpivots);
1547#endif
1548 dd_WriteLPMode(f);
1549 dd_WriteTimes(f,dd_statStartTime, currenttime);
1550}
1551
1552void dd_WriteLPMode(FILE *f)
1553{
1554 fprintf(f, "\n* LP solver: ");
1555 switch (dd_choiceLPSolverDefault) {
1556 case dd_DualSimplex:
1557 fprintf(f, "DualSimplex\n");
1558 break;
1559 case dd_CrissCross:
1560 fprintf(f, "Criss-Cross\n");
1561 break;
1562 default: break;
1563 }
1564
1565 fprintf(f, "* Redundancy cheking solver: ");
1566 switch (dd_choiceRedcheckAlgorithm) {
1567 case dd_DualSimplex:
1568 fprintf(f, "DualSimplex\n");
1569 break;
1570 case dd_CrissCross:
1571 fprintf(f, "Criss-Cross\n");
1572 break;
1573 default: break;
1574 }
1575
1576 fprintf(f, "* Lexicographic pivot: ");
1577 if (dd_choiceLexicoPivotQ) fprintf(f, " on\n");
1578 else fprintf(f, " off\n");
1579
1580}
1581
1582
1583void dd_WriteRunningMode(FILE *f, dd_PolyhedraPtr poly)
1584{
1585 if (poly->child!=NULL){
1586 fprintf(f,"* roworder: ");
1587 switch (poly->child->HalfspaceOrder) {
1588
1589 case dd_MinIndex:
1590 fprintf(f, "minindex\n");
1591 break;
1592
1593 case dd_MaxIndex:
1594 fprintf(f, "maxindex\n");
1595 break;
1596
1597 case dd_MinCutoff:
1598 fprintf(f, "mincutoff\n");
1599 break;
1600
1601 case dd_MaxCutoff:
1602 fprintf(f, "maxcutoff\n");
1603 break;
1604
1605 case dd_MixCutoff:
1606 fprintf(f, "mixcutoff\n");
1607 break;
1608
1609 case dd_LexMin:
1610 fprintf(f, "lexmin\n");
1611 break;
1612
1613 case dd_LexMax:
1614 fprintf(f, "lexmax\n");
1615 break;
1616
1617 case dd_RandomRow:
1618 fprintf(f, "random %d\n",poly->child->rseed);
1619 break;
1620
1621 default: break;
1622 }
1623 }
1624}
1625
1626
1627void dd_WriteCompletionStatus(FILE *f, dd_ConePtr cone)
1628{
1629 if (cone->Iteration<cone->m && cone->CompStatus==dd_AllFound) {
1630 fprintf(f,"*Computation completed at Iteration %4ld.\n", cone->Iteration);
1631 }
1632 if (cone->CompStatus == dd_RegionEmpty) {
1633 fprintf(f,"*Computation completed at Iteration %4ld because the region found empty.\n",cone->Iteration);
1634 }
1635}
1636
1637void dd_WritePolyFile(FILE *f, dd_PolyhedraPtr poly)
1638{
1639 dd_WriteAmatrix(f,poly->A,poly->m,poly->d);
1640}
1641
1642
1643void dd_WriteErrorMessages(FILE *f, dd_ErrorType Error)
1644{
1645 switch (Error) {
1646
1647 case dd_DimensionTooLarge:
1648 fprintf(f, "*Input Error: Input matrix is too large:\n");
1649 fprintf(f, "*Please increase MMAX and/or NMAX in the source code and recompile.\n");
1650 break;
1651
1652 case dd_IFileNotFound:
1653 fprintf(f, "*Input Error: Specified input file does not exist.\n");
1654 break;
1655
1656 case dd_OFileNotOpen:
1657 fprintf(f, "*Output Error: Specified output file cannot be opened.\n");
1658 break;
1659
1660 case dd_NegativeMatrixSize:
1661 fprintf(f, "*Input Error: Input matrix has a negative size:\n");
1662 fprintf(f, "*Please check rowsize or colsize.\n");
1663 break;
1664
1665 case dd_ImproperInputFormat:
1666 fprintf(f,"*Input Error: Input format is not correct.\n");
1667 fprintf(f,"*Format:\n");
1668 fprintf(f," begin\n");
1669 fprintf(f," m n NumberType(real, rational or integer)\n");
1670 fprintf(f," b -A\n");
1671 fprintf(f," end\n");
1672 break;
1673
1674 case dd_EmptyVrepresentation:
1675 fprintf(f, "*Input Error: V-representation is empty:\n");
1676 fprintf(f, "*cddlib does not accept this trivial case for which output can be any inconsistent system.\n");
1677 break;
1678
1679 case dd_EmptyHrepresentation:
1680 fprintf(f, "*Input Error: H-representation is empty.\n");
1681 break;
1682
1683 case dd_EmptyRepresentation:
1684 fprintf(f, "*Input Error: Representation is empty.\n");
1685 break;
1686
1687 case dd_NoLPObjective:
1688 fprintf(f, "*LP Error: No LP objective (max or min) is set.\n");
1689 break;
1690
1691 case dd_NoRealNumberSupport:
1692 fprintf(f, "*LP Error: The binary (with GMP Rational) does not support Real number input.\n");
1693 fprintf(f, " : Use a binary compiled without -DGMPRATIONAL option.\n");
1694 break;
1695
1696 case dd_NotAvailForH:
1697 fprintf(f, "*Error: A function is called with H-rep which does not support an H-representation.\n");
1698 break;
1699
1700 case dd_NotAvailForV:
1701 fprintf(f, "*Error: A function is called with V-rep which does not support an V-representation.\n");
1702 break;
1703
1704 case dd_CannotHandleLinearity:
1705 fprintf(f, "*Error: The function called cannot handle linearity.\n");
1706 break;
1707
1708 case dd_RowIndexOutOfRange:
1709 fprintf(f, "*Error: Specified row index is out of range\n");
1710 break;
1711
1712 case dd_ColIndexOutOfRange:
1713 fprintf(f, "*Error: Specified column index is out of range\n");
1714 break;
1715
1716 case dd_LPCycling:
1717 fprintf(f, "*Error: Possibly an LP cycling occurs. Use the Criss-Cross method.\n");
1718 break;
1719
1720 case dd_NumericallyInconsistent:
1721 fprintf(f, "*Error: Numerical inconsistency is found. Use the GMP exact arithmetic.\n");
1722 break;
1723
1724 case dd_NoError:
1725 fprintf(f,"*No Error found.\n");
1726 break;
1727 }
1728}
1729
1730
1731dd_SetFamilyPtr dd_CopyIncidence(dd_PolyhedraPtr poly)
1732{
1733 dd_SetFamilyPtr F=NULL;
1734 dd_bigrange k;
1735 dd_rowrange i;
1736
1737 if (poly->child==NULL || poly->child->CompStatus!=dd_AllFound) goto _L99;
1738 if (poly->AincGenerated==dd_FALSE) dd_ComputeAinc(poly);
1739 F=dd_CreateSetFamily(poly->n, poly->m1);
1740 for (i=1; i<=poly->m1; i++)
1741 for (k=1; k<=poly->n; k++)
1742 if (set_member(k,poly->Ainc[i-1])) set_addelem(F->set[k-1],i);
1743_L99:;
1744 return F;
1745}
1746
1747dd_SetFamilyPtr dd_CopyInputIncidence(dd_PolyhedraPtr poly)
1748{
1749 dd_rowrange i;
1750 dd_SetFamilyPtr F=NULL;
1751
1752 if (poly->child==NULL || poly->child->CompStatus!=dd_AllFound) goto _L99;
1753 if (poly->AincGenerated==dd_FALSE) dd_ComputeAinc(poly);
1754 F=dd_CreateSetFamily(poly->m1, poly->n);
1755 for(i=0; i< poly->m1; i++){
1756 set_copy(F->set[i], poly->Ainc[i]);
1757 }
1758_L99:;
1759 return F;
1760}
1761
1762dd_SetFamilyPtr dd_CopyAdjacency(dd_PolyhedraPtr poly)
1763{
1764 dd_RayPtr RayPtr1,RayPtr2;
1765 dd_SetFamilyPtr F=NULL;
1766 long pos1, pos2;
1767 dd_bigrange lstart,k,n;
1768 set_type linset,allset;
1769 dd_boolean adj;
1770
1771 if (poly->n==0 && poly->homogeneous && poly->representation==dd_Inequality){
1772 n=1; /* the origin (the unique vertex) should be output. */
1773 } else n=poly->n;
1774 set_initialize(&linset, n);
1775 set_initialize(&allset, n);
1776 if (poly->child==NULL || poly->child->CompStatus!=dd_AllFound) goto _L99;
1777 F=dd_CreateSetFamily(n, n);
1778 if (n<=0) goto _L99;
1779 poly->child->LastRay->Next=NULL;
1780 for (RayPtr1=poly->child->FirstRay, pos1=1;RayPtr1 != NULL;
1781 RayPtr1 = RayPtr1->Next, pos1++){
1782 for (RayPtr2=poly->child->FirstRay, pos2=1; RayPtr2 != NULL;
1783 RayPtr2 = RayPtr2->Next, pos2++){
1784 if (RayPtr1!=RayPtr2){
1785 dd_CheckAdjacency(poly->child, &RayPtr1, &RayPtr2, &adj);
1786 if (adj){
1787 set_addelem(F->set[pos1-1], pos2);
1788 }
1789 }
1790 }
1791 }
1792 lstart=poly->n - poly->ldim + 1;
1793 set_compl(allset,allset); /* allset is set to the ground set. */
1794 for (k=lstart; k<=poly->n; k++){
1795 set_addelem(linset,k); /* linearity set */
1796 set_copy(F->set[k-1],allset); /* linearity generator is adjacent to all */
1797 }
1798 for (k=1; k<lstart; k++){
1799 set_uni(F->set[k-1],F->set[k-1],linset);
1800 /* every generator is adjacent to all linearity generators */
1801 }
1802_L99:;
1803 set_free(allset); set_free(linset);
1804 return F;
1805}
1806
1807dd_SetFamilyPtr dd_CopyInputAdjacency(dd_PolyhedraPtr poly)
1808{
1809 dd_rowrange i,j;
1810 dd_SetFamilyPtr F=NULL;
1811
1812 if (poly->child==NULL || poly->child->CompStatus!=dd_AllFound) goto _L99;
1813 if (poly->AincGenerated==dd_FALSE) dd_ComputeAinc(poly);
1814 F=dd_CreateSetFamily(poly->m1, poly->m1);
1815 for (i=1; i<=poly->m1; i++){
1816 for (j=1; j<=poly->m1; j++){
1817 if (i!=j && dd_InputAdjacentQ(poly, i, j)) {
1818 set_addelem(F->set[i-1],j);
1819 }
1820 }
1821 }
1822_L99:;
1823 return F;
1824}
1825
1826dd_MatrixPtr dd_CopyOutput(dd_PolyhedraPtr poly)
1827{
1828 dd_RayPtr RayPtr;
1829 dd_MatrixPtr M=NULL;
1830 dd_rowrange i=0,total;
1831 dd_colrange j,j1;
1832 mytype b;
1833 dd_RepresentationType outputrep=dd_Inequality;
1834 dd_boolean outputorigin=dd_FALSE;
1835
1836 dd_init(b);
1837 total=poly->child->LinearityDim + poly->child->FeasibleRayCount;
1838
1839 if (poly->child->d<=0 || poly->child->newcol[1]==0) total=total-1;
1840 if (poly->representation==dd_Inequality) outputrep=dd_Generator;
1841 if (total==0 && poly->homogeneous && poly->representation==dd_Inequality){
1842 total=1;
1843 outputorigin=dd_TRUE;
1844 /* the origin (the unique vertex) should be output. */
1845 }
1846 if (poly->child==NULL || poly->child->CompStatus!=dd_AllFound) goto _L99;
1847
1848 M=dd_CreateMatrix(total, poly->d);
1849 RayPtr = poly->child->FirstRay;
1850 while (RayPtr != NULL) {
1851 if (RayPtr->feasible) {
1852 dd_CopyRay(M->matrix[i], poly->d, RayPtr, outputrep, poly->child->newcol);
1853 i++; /* 086 */
1854 }
1855 RayPtr = RayPtr->Next;
1856 }
1857 for (j=2; j<=poly->d; j++){
1858 if (poly->child->newcol[j]==0){
1859 /* original column j is dependent on others and removed for the cone */
1860 dd_set(b,poly->child->Bsave[0][j-1]);
1861 if (outputrep==dd_Generator && dd_Positive(b)){
1862 dd_set(M->matrix[i][0],dd_one); /* dd_Normalize */
1863 for (j1=1; j1<poly->d; j1++)
1864 dd_div(M->matrix[i][j1],(poly->child->Bsave[j1][j-1]),b);
1865 } else {
1866 for (j1=0; j1<poly->d; j1++)
1867 dd_set(M->matrix[i][j1],poly->child->Bsave[j1][j-1]);
1868 }
1869 set_addelem(M->linset, i+1);
1870 i++;
1871 }
1872 }
1873 if (outputorigin){
1874 /* output the origin for homogeneous H-polyhedron with no rays. */
1875 dd_set(M->matrix[0][0],dd_one);
1876 for (j=1; j<poly->d; j++){
1877 dd_set(M->matrix[0][j],dd_purezero);
1878 }
1879 }
1880 dd_MatrixIntegerFilter(M);
1881 if (poly->representation==dd_Inequality)
1882 M->representation=dd_Generator;
1883 else
1884 M->representation=dd_Inequality;
1885_L99:;
1886 dd_clear(b);
1887 return M;
1888}
1889
1890dd_MatrixPtr dd_CopyInput(dd_PolyhedraPtr poly)
1891{
1892 dd_MatrixPtr M=NULL;
1893 dd_rowrange i;
1894
1895 M=dd_CreateMatrix(poly->m, poly->d);
1896 dd_CopyAmatrix(M->matrix, poly->A, poly->m, poly->d);
1897 for (i=1; i<=poly->m; i++)
1898 if (poly->EqualityIndex[i]==1) set_addelem(M->linset,i);
1899 dd_MatrixIntegerFilter(M);
1900 if (poly->representation==dd_Generator)
1901 M->representation=dd_Generator;
1902 else
1903 M->representation=dd_Inequality;
1904 return M;
1905}
1906
1907dd_MatrixPtr dd_CopyGenerators(dd_PolyhedraPtr poly)
1908{
1909 dd_MatrixPtr M=NULL;
1910
1911 if (poly->representation==dd_Generator){
1912 M=dd_CopyInput(poly);
1913 } else {
1914 M=dd_CopyOutput(poly);
1915 }
1916 return M;
1917}
1918
1919dd_MatrixPtr dd_CopyInequalities(dd_PolyhedraPtr poly)
1920{
1921 dd_MatrixPtr M=NULL;
1922
1923 if (poly->representation==dd_Inequality){
1924 M=dd_CopyInput(poly);
1925 } else {
1926 M=dd_CopyOutput(poly);
1927 }
1928 return M;
1929}
1930
1931/****************************************************************************************/
1932/* rational number (a/b) read is taken from Vinci by Benno Bueeler and Andreas Enge */
1933/****************************************************************************************/
Brian Silvermanf1cff392015-10-11 19:36:18 -04001934void dd_sread_rational_value (char *s, mytype value)
Austin Schuh405fa6c2015-09-06 18:13:55 -07001935 /* reads a rational value from the specified string "s" and assigns it to "value" */
1936
1937{
1938 char *numerator_s=NULL, *denominator_s=NULL, *position;
1939 int sign = 1;
1940 double numerator, denominator;
1941#if defined GMPRATIONAL
1942 mpz_t znum, zden;
1943#else
1944 double rvalue;
1945#endif
1946
1947 /* determine the sign of the number */
1948 numerator_s = s;
1949 if (s [0] == '-')
1950 { sign = -1;
1951 numerator_s++;
1952 }
1953 else if (s [0] == '+')
1954 numerator_s++;
1955
1956 /* look for a sign '/' and eventually split the number in numerator and denominator */
1957 position = strchr (numerator_s, '/');
1958 if (position != NULL)
1959 { *position = '\0'; /* terminates the numerator */
1960 denominator_s = position + 1;
1961 };
1962
1963 /* determine the floating point values of numerator and denominator */
1964 numerator=atol (numerator_s);
1965
1966 if (position != NULL)
1967 {
1968 denominator=atol (denominator_s);
1969 }
1970 else denominator = 1;
1971
1972/*
1973 fprintf(stderr,"\nrational_read: numerator %f\n",numerator);
1974 fprintf(stderr,"rational_read: denominator %f\n",denominator);
1975 fprintf(stderr,"rational_read: sign %d\n",sign);
1976*/
1977
1978#if defined GMPRATIONAL
1979 mpz_init_set_str(znum,numerator_s,10);
1980 if (sign<0) mpz_neg(znum,znum);
1981 mpz_init(zden); mpz_set_ui(zden,1);
1982 if (denominator_s!=NULL) mpz_init_set_str(zden,denominator_s,10);
1983 mpq_set_num(value,znum); mpq_set_den(value,zden);
1984 mpq_canonicalize(value);
1985 mpz_clear(znum); mpz_clear(zden);
1986 /* num=(long)sign * numerator; */
1987 /* den=(unsigned long) denominator; */
1988 /* mpq_set_si(value, num, den); */
1989#elif defined GMPFLOAT
1990 rvalue=sign * numerator/ (signed long) denominator;
1991 mpf_set_d(value, rvalue);
1992#else
1993 rvalue=sign * numerator/ (signed long) denominator;
1994 ddd_set_d(value, rvalue);
1995#endif
1996 if (dd_debug) {
1997 fprintf(stderr,"rational_read: ");
1998 dd_WriteNumber(stderr,value); fprintf(stderr,"\n");
1999 }
2000}
2001
2002
2003void dd_fread_rational_value (FILE *f, mytype value)
2004 /* reads a rational value from the specified file "f" and assigns it to "value" */
2005
2006{
2007 char number_s [dd_wordlenmax];
2008 mytype rational_value;
2009
2010 dd_init(rational_value);
2011 fscanf(f, "%s ", number_s);
2012 dd_sread_rational_value (number_s, rational_value);
2013 dd_set(value,rational_value);
2014 dd_clear(rational_value);
2015}
2016
2017/****************************************************************************************/
2018
2019
2020/* end of cddio.c */
2021